diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 8797c4074..508d005a4 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -250,8 +250,9 @@ class ApplicationController < ActionController::Base
 		# 开放课程通过链接访问的用户
 		if !User.current.logged? && !params[:chinaoocTimestamp].blank? && !params[:websiteName].blank? && !params[:chinaoocKey].blank?
 			content = "#{OPENKEY}#{params[:websiteName]}#{params[:chinaoocTimestamp]}"
+
 			if Digest::MD5.hexdigest(content) == params[:chinaoocKey]
-				user = User.open_class_user
+				user = open_class_user
 				start_user_session(user) if user
 				User.current = user
 			end
@@ -615,4 +616,27 @@ class ApplicationController < ActionController::Base
 	def set_export_cookies
 		cookies[:fileDownload] = true
 	end
+
+	# 149课程的评审用户数据创建(包含创建课堂学生)
+	def open_class_user
+		user = User.find_by(login: "OpenClassUser")
+		unless user
+			ActiveRecord::Base.transaction do
+				user_params = {status: 1, login: "OpenClassUser", lastname: "开放课程",
+											 nickname: "开放课程", professional_certification: 1, certification: 1, grade: 0,
+											 password: "12345678", phone: "11122223333", profile_completed: 1}
+				user = User.create!(user_params)
+
+				UserExtension.create!(user_id: user.id, gender: 0, school_id: 3396, :identity => 1, :student_id => "openclassuser") # 3396
+
+				subject = Subject.find_by(id: 149)
+				if subject
+					subject.courses.each do |course|
+						CourseMember.create!(course_id: course.id, role: 3, user_id: user.id) if !course.course_members.exists?(user_id: user.id)
+					end
+				end
+			end
+		end
+		user
+	end
 end
diff --git a/app/controllers/colleges_controller.rb b/app/controllers/colleges_controller.rb
index 66d327649..f869e9ec6 100644
--- a/app/controllers/colleges_controller.rb
+++ b/app/controllers/colleges_controller.rb
@@ -40,8 +40,8 @@ class CollegesController < ApplicationController
 
   def teachers
     @teachers = User.find_by_sql("SELECT users.id, users.login, users.lastname, users.firstname, users.nickname, IFNULL((SELECT count(shixuns.id) FROM shixuns where shixuns.user_id =users.id group by shixuns.user_id), 0) AS publish_shixun_count,
-                                (SELECT count(c.id) FROM courses c, course_members m WHERE c.id != 1309 and m.course_id = c.id AND m.role in (1,2,3) and c.school_id = #{current_school.id} AND m.user_id=users.id AND c.is_delete = 0) as course_count
-                                FROM `users`, user_extensions ue where users.id=ue.user_id and ue.identity=0 and ue.school_id=#{current_school.id} ORDER BY publish_shixun_count desc, course_count desc, id desc LIMIT 10")
+                                (SELECT count(c.id) FROM courses c, course_members m WHERE c.id != 1309 and m.course_id = c.id AND m.user_id=users.id AND m.role in (1,2,3) and c.school_id = #{current_school.id} AND c.is_delete = 0) as course_count
+                                FROM `users`, user_extensions ue where ue.school_id=#{current_school.id} and users.id=ue.user_id and ue.identity=0 ORDER BY publish_shixun_count desc, course_count desc, id desc LIMIT 10")
     # ).order("publish_shixun_count desc, experience desc").limit(10)
     @teachers =
       @teachers.map do |teacher|
diff --git a/app/controllers/commons_controller.rb b/app/controllers/commons_controller.rb
index 0c0fe79af..43ea31c97 100644
--- a/app/controllers/commons_controller.rb
+++ b/app/controllers/commons_controller.rb
@@ -51,7 +51,8 @@ class CommonsController < ApplicationController
           200
         end
       when 'journals_for_message'
-        if current_user.course_identity(@object.jour.course)  >= Course::STUDENT && @object.user != current_user
+        course = @object.jour&.course || @object.jour&.student_work&.homework_common&.course
+        if current_user.course_identity(course)  >= Course::STUDENT && @object.user != current_user
           403
         else
           200
diff --git a/app/controllers/ecs/students_controller.rb b/app/controllers/ecs/students_controller.rb
index c21d625e0..abc5ddb65 100644
--- a/app/controllers/ecs/students_controller.rb
+++ b/app/controllers/ecs/students_controller.rb
@@ -14,7 +14,7 @@ class Ecs::StudentsController < Ecs::BaseController
   end
 
   def import
-    success_count = Ecs::ImportStudentService.call(current_year, params[:attachment_id])
+    success_count = Ecs::ImportStudentService.call(current_year, params)
     render_ok(success_count: success_count)
   rescue Ecs::ImportStudentService::Error => ex
     render_error(ex.message)
diff --git a/app/controllers/games_controller.rb b/app/controllers/games_controller.rb
index b9da12ab0..4a087ae7a 100644
--- a/app/controllers/games_controller.rb
+++ b/app/controllers/games_controller.rb
@@ -559,7 +559,7 @@ class GamesController < ApplicationController
     secret_rep = @shixun.shixun_secret_repository
     logger.info("############secret_rep: #{secret_rep}")
     if secret_rep&.repo_name
-      secretGitUrl = repo_url secret_rep.repo_path
+      secretGitUrl = repo_ip_url secret_rep.repo_path
       br_params.merge!({secretGitUrl:  Base64.urlsafe_encode64(secretGitUrl), secretDir: secret_rep.secret_dir_path})
       logger.info("#######br_params:#{br_params}")
     end
diff --git a/app/controllers/graduation_tasks_controller.rb b/app/controllers/graduation_tasks_controller.rb
index 6a0ce85a9..8792959d8 100644
--- a/app/controllers/graduation_tasks_controller.rb
+++ b/app/controllers/graduation_tasks_controller.rb
@@ -171,7 +171,7 @@ class GraduationTasksController < ApplicationController
         end
       end
     else
-      @work_list = @work
+      @work_list = !@task.published? ? [] : @work
       @view_work = false
       @work_count = @work_list.count
       @all_work_count = @work_list.count
diff --git a/app/models/graduation_work.rb b/app/models/graduation_work.rb
index 73c217114..94c2633ae 100644
--- a/app/models/graduation_work.rb
+++ b/app/models/graduation_work.rb
@@ -55,7 +55,7 @@ class GraduationWork < ApplicationRecord
 
   def delete_atta atta
     last_score = graduation_work_scores.where.not(score: nil).last
-    atta.author_id == user_id && (!last_score.present? || last_score.try(:created_at) < atta.created_on)
+    (atta.author_id == User.current.id) && (last_score.blank? || last_score.try(:created_at) < atta.created_on)
   end
 
   # 分班名
diff --git a/app/models/student_work.rb b/app/models/student_work.rb
index 6b4025885..2e7f843ae 100644
--- a/app/models/student_work.rb
+++ b/app/models/student_work.rb
@@ -106,7 +106,7 @@ class StudentWork < ApplicationRecord
 
   def delete_atta atta
     last_score = student_works_scores.where.not(score: nil).last
-    atta.author_id == user_id && (!last_score.present? || last_score.try(:created_at) < atta.created_on)
+    (atta.author_id == User.current.id) && (last_score.blank? || last_score.try(:created_at) < atta.created_on)
   end
 
   # 作品总体评价
diff --git a/app/models/student_works_score.rb b/app/models/student_works_score.rb
index 86d393f93..299b61596 100644
--- a/app/models/student_works_score.rb
+++ b/app/models/student_works_score.rb
@@ -1,6 +1,6 @@
 class StudentWorksScore < ApplicationRecord
   #appeal_status: 0:正常;1:申诉中,2:撤销申诉;3:申诉成功;4:申诉被拒绝;5:申诉失效
-belongs_to :student_work
+  belongs_to :student_work
   belongs_to :user
   has_many :journals_for_messages, -> { order('created_on desc') }, as: :jour, dependent: :destroy
   has_one :student_works_scores_appeal, dependent: :destroy
diff --git a/app/models/user.rb b/app/models/user.rb
index ebf68cce6..70cd54c92 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -1,686 +1,663 @@
-class User < ApplicationRecord
-  include Watchable
-  include Searchable::Dependents::User
-
-  # Account statuses
-  STATUS_ANONYMOUS  = 0
-  STATUS_ACTIVE     = 1
-  STATUS_REGISTERED = 2
-  STATUS_LOCKED     = 3
-
-  # tpi tpm权限控制
-  EDU_ADMIN = 1       # 超级管理员
-  EDU_BUSINESS = 2    # 运营人员
-  EDU_SHIXUN_MANAGER = 3 # 实训管理员
-  EDU_SHIXUN_MEMBER = 4  # 实训成员
-  EDU_CERTIFICATION_TEACHER = 5 # 平台认证的老师
-  EDU_GAME_MANAGER = 6     # TPI的创建者
-  EDU_TEACHER = 7 # 平台老师,但是未认证
-  EDU_NORMAL = 8  # 普通用户
-
-  VALID_EMAIL_REGEX = /^[a-zA-Z0-9]+([.\-_\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/i
-  VALID_PHONE_REGEX = /^1\d{10}$/
-
-  LOGIN_LENGTH_LIMIT = 30
-  MAIL_LENGTH_LMIT = 60
-
-  MIX_PASSWORD_LIMIT = 8
-
-  has_one :user_extension, dependent: :destroy
-  accepts_nested_attributes_for :user_extension, update_only: true
-
-  has_many :memos, foreign_key: 'author_id'
-  has_many :created_shixuns, class_name: 'Shixun'
-  has_many :shixun_members, :dependent => :destroy
-  has_many :shixuns, :through => :shixun_members
-  has_many :myshixuns, :dependent => :destroy
-  has_many :study_shixuns, through: :myshixuns, source: :shixun   # 已学习的实训
-  has_many :course_messages
-  has_many :courses, dependent: :destroy
-
-  #试卷
-  has_many :exercise_banks, :dependent => :destroy
-  has_many :exercise_users, :dependent => :destroy
-  has_many :exercise_answers, :dependent => :destroy  #针对每个题目学生的答案
-  has_many :exercise_shixun_answers, :dependent => :destroy  #针对每个实训题目学生的答案
-  has_many :exercise_answer_comments, :dependent => :destroy
-  has_many :exercises, :dependent => :destroy  #创建的试卷
-
-  has_many :homework_banks, dependent: :destroy
-
-  has_many :graduation_works, dependent: :destroy
-
-  has_many :students_for_courses, foreign_key: :student_id, dependent: :destroy
-  has_one :onclick_time, :dependent => :destroy
-
-  # 新版私信
-  has_many :private_messages, dependent: :destroy
-  has_many :recent_contacts, through: :private_messages, source: :target
-  has_many :tidings, :dependent => :destroy
-
-  has_many :games, :dependent => :destroy
-  has_many :created_subjects, foreign_key: :user_id, class_name: 'Subject'
-  has_many :subject_members, :dependent => :destroy
-  has_many :subjects, :through => :subject_members
-  has_many :grades, :dependent => :destroy
-  has_many :experiences, :dependent => :destroy
-  has_many :student_works, :dependent => :destroy
-  has_many :student_works_scores
-  has_many :student_works_evaluation_distributions
-
-  # 毕业设计
-  has_many :graduation_topics, :dependent => :destroy
-  has_many :student_graduation_topics, :dependent => :destroy
-
-  # 题库
-  has_many :question_banks, :dependent => :destroy
-  # 毕设任务题库
-  has_many :gtask_banks, dependent: :destroy
-  has_many :gtopic_banks, dependent: :destroy
-
-  #问卷
-  has_many :course_members, :dependent => :destroy
-  has_many :poll_votes, :dependent => :destroy
-  has_many :poll_users, :dependent => :destroy
-
-  has_many :messages,foreign_key: 'author_id',:dependent => :destroy
-
-  has_many :journals_for_messages, :as => :jour, :dependent => :destroy
-  has_many :teacher_course_groups, :dependent => :destroy
-
-  has_many :attachments,foreign_key: :author_id, :dependent => :destroy
-
-  # 工程认证
-  has_many :ec_school_users,:dependent => :destroy
-  has_many :schools, :through => :ec_school_users
-
-  has_many :ec_major_school_users, :dependent => :destroy
-  has_many :ec_major_schools, :through => :ec_major_school_users
-
-  has_many :ec_course_users
-
-  has_many :department_members, dependent: :destroy #部门管理员
-
-  # 课堂
-  has_many :student_course_members, -> { course_students }, class_name: 'CourseMember'
-  has_many :as_student_courses, through: :student_course_members, source: :course
-  has_many :manage_course_members, -> { teachers_and_admin }, class_name: 'CourseMember'
-  has_many :manage_courses, through: :manage_course_members, source: :course
-
-  # 关注
-  has_many :be_watchers, foreign_key: :user_id, dependent: :destroy # 我的关注
-  has_many :be_watcher_users, through: :be_watchers, dependent: :destroy # 我关注的用户
-
-  # 认证
-  has_many :apply_user_authentication
-  has_one :process_real_name_apply, -> { processing.real_name_auth.order(created_at: :desc) }, class_name: 'ApplyUserAuthentication'
-  has_one :process_professional_apply, -> { processing.professional_auth.order(created_at: :desc) }, class_name: 'ApplyUserAuthentication'
-  has_many :apply_actions, dependent: :destroy
-  has_many :trail_auth_apply_actions, -> { where(container_type: 'TrialAuthorization') }, class_name: 'ApplyAction'
-
-  has_many :attendances
-
-  # 兴趣
-  has_many :user_interests, dependent: :delete_all
-  has_many :interests, through: :user_interests, source: :repertoire
-
-  # 众包
-  has_many :project_packages, foreign_key: :creator_id, dependent: :destroy
-  has_many :bidding_users, dependent: :destroy
-  has_many :bidden_project_packages, through: :bidding_users, source: :project_package
-
-  # 项目
-  has_many :applied_projects, dependent: :destroy
-
-  # 教学案例
-  has_many :libraries, dependent: :destroy
-
-  # 视频
-  has_many :videos, dependent: :destroy
-
-  # 客户管理
-  belongs_to :partner, optional: true
-
-  # Groups and active users
-  scope :active, lambda { where(status: STATUS_ACTIVE) }
-
-  attr_accessor :password, :password_confirmation
-
-  delegate :gender, :department_id, :school_id, :location, :location_city, :technical_title, to: :user_extension, allow_nil: true
-
-  before_save :update_hashed_password
-
-  #
-  # validations
-  #
-  validates_presence_of :login, :if => Proc.new { |user| !user.is_a?(AnonymousUser) }, case_sensitive: false
-  validates_uniqueness_of :login, :if => Proc.new { |user| user.login_changed? && user.login.present? }, case_sensitive: false
-  validates_uniqueness_of :mail, :if => Proc.new { |user| user.mail_changed? && user.mail.present? }, case_sensitive: false
-  validates_uniqueness_of :phone, :if => Proc.new { |user| user.phone_changed? && user.phone.present? }, case_sensitive: false
-  validates_length_of :login, maximum: LOGIN_LENGTH_LIMIT
-  validates_length_of :mail, maximum: MAIL_LENGTH_LMIT
-  # validates_format_of :mail, with: VALID_EMAIL_REGEX, multiline: true
-  # validates_format_of :phone, with: VALID_PHONE_REGEX, multiline: true
-  validate :validate_password_length
-
-  # validates :nickname, presence: true, length: { maximum: 10 }
-  # validates :lastname, presence: true
-
-  # 删除自动登录的token,一旦退出下次会提示需要登录
-  def delete_autologin_token(value)
-    Token.where(:user_id => id, :action => 'autologin', :value => value).delete_all
-  end
-
-  def delete_session_token(value)
-    Token.where(:user_id => id, :action => 'session', :value => value).delete_all
-  end
-
-  def git_mail
-    mail.blank? ? "#{login}@educoder.net" : mail
-  end
-
-  # 学号
-  def student_id
-    self.user_extension.try(:student_id)
-  end
-
-  # 关注数
-  def follow_count
-    Watcher.where(user_id: id, watchable_type: %w(Principal User)).count
-    # User.watched_by(id).count
-  end
-
-  # 粉丝数
-  def fan_count
-    Watcher.where(watchable_type: %w(Principal User), watchable_id: id).count
-    # watchers.count
-  end
-
-  # 判断当前用户是否为老师
-  def is_teacher?
-    self.user_extension.teacher?
-  end
-
-  # 平台认证的老师
-  def is_certification_teacher
-    self.user_extension.teacher? && self.professional_certification
-  end
-
-  def certification_teacher?
-    professional_certification? && user_extension.teacher?
-  end
-
-  # 判断用户的身份
-  def identity
-    ue = self.user_extension
-    unless ue.blank?
-      if ue.teacher?
-        ue.technical_title ? ue.technical_title : "老师"
-      elsif ue.student?
-        "学生"
-      else
-        ue.technical_title ? ue.technical_title : "专业人士"
-      end
-    end
-  end
-
-  # 判断当前用户是否通过职业认证
-  def pro_certification?
-    professional_certification
-  end
-
-  # 用户的学校名称
-  def school_name
-    user_extension&.school&.name || ''
-  end
-
-  # 用户的学院名称
-  def department_name
-    user_extension&.department&.name || ''
-  end
-
-  # 课堂的老师(创建者、老师、助教)
-  def teacher_of_course?(course)
-    course.course_members.exists?(user_id: id, role: [1,2,3], is_active: 1) || admin? || business?
-  end
-
-  # 课堂的老师(创建者、老师、助教),不用考虑当前身份
-  def teacher_of_course_non_active?(course)
-    course.course_members.exists?(user_id: id, role: [1,2,3])
-  end
-
-  # 是否是教师,课堂管理员或者超级管理员
-  def teacher_or_admin?(course)
-    course.course_members.exists?(user_id: id, role: [1,2], is_active: 1) || admin? || business?
-  end
-
-  # 课堂的创建者(考虑到多重身份的用户)
-  def creator_of_course?(course)
-    course.course_members.exists?(user_id: id, role: 1, is_active: 1) || admin? || business?
-  end
-
-  # 课堂的学生
-  def student_of_course?(course)
-    course.course_members.exists?(user_id: id, role: %i[STUDENT])
-  end
-
-  # 课堂成员
-  def member_of_course?(course)
-    course&.course_members.exists?(user_id: id)
-  end
-
-  # 实训路径管理员
-  def creator_of_subject?(subject)
-    subject.user_id == id || admin?
-  end
-
-  # 实训路径:合作者、admin
-  def manager_of_subject?(subject)
-    subject.subject_members.exists?(user_id: id, role: [1,2]) || admin?
-  end
-
-  # 实训管理员:实训合作者、admin
-  def manager_of_shixun?(shixun)
-     shixun.shixun_members.exists?(role: [1,2], user_id: id) || admin? || business?
-  end
-
-  # 实训管理员
-  def creator_of_shixun?(shixun)
-    id == shixun.user_id
-  end
-
-  # 实训的合作者
-  def member_of_shixun?(shixun)
-    #self.shixun_members.where(:role => 2, :shixun_id => shixun.id).present?
-    shixun.shixun_members.exists?(role: 2, user_id: id)
-  end
-
-  # TPI的创建者
-  def creator_of_game?(game)
-    id == game.user_id
-  end
-
-  # 用户账号状态
-  def active?
-    status == STATUS_ACTIVE
-  end
-
-  def registered?
-    status == STATUS_REGISTERED
-  end
-
-  def locked?
-    status == STATUS_LOCKED
-  end
-
-  def activate
-    self.status = STATUS_ACTIVE
-  end
-
-  def register
-    self.status = STATUS_REGISTERED
-  end
-
-  def lock
-    self.status = STATUS_LOCKED
-  end
-
-  def activate!
-    update_attribute(:status, STATUS_ACTIVE)
-  end
-
-  def register!
-    update_attribute(:status, STATUS_REGISTERED)
-  end
-
-  def lock!
-    update_attribute(:status, STATUS_LOCKED)
-  end
-
-  # 课程用户身份
-  def course_identity(course)
-    if !logged?
-      Course::Anonymous
-    elsif admin?
-      Course::ADMIN
-    elsif business?
-      Course::BUSINESS
-    else
-      role = course.course_members.find_by(user_id: id, is_active: 1)&.role
-      case role
-      when nil                   then Course::NORMAL
-      when 'CREATOR'             then Course::CREATOR
-      when 'PROFESSOR'           then Course::PROFESSOR
-      when 'STUDENT'             then Course::STUDENT
-      when 'ASSISTANT_PROFESSOR' then Course::ASSISTANT_PROFESSOR
-      end
-    end
-  end
-
-  # 实训用户身份
-  def shixun_identity(shixun)
-    @identity =
-        if admin?
-          User::EDU_ADMIN
-        elsif business?
-          User::EDU_BUSINESS
-        elsif creator_of_shixun?(shixun)
-          User::EDU_SHIXUN_MANAGER
-        elsif member_of_shixun?(shixun)
-          User::EDU_SHIXUN_MEMBER
-        elsif is_certification_teacher
-          User::EDU_CERTIFICATION_TEACHER
-        elsif is_teacher?
-          User::EDU_TEACHER
-        else
-          User::EDU_NORMAL
-        end
-    return @identity
-  end
-
-  # tpi的用户身份
-  def game_identity(game)
-    shixun = game.myshixun.shixun
-    @identity =
-        if admin?
-          User::EDU_ADMIN
-        elsif business?
-          User::EDU_BUSINESS
-        elsif creator_of_shixun?(shixun)
-          User::EDU_SHIXUN_MANAGER
-        elsif member_of_shixun?(shixun)
-          User::EDU_SHIXUN_MEMBER
-        elsif is_certification_teacher
-          User::EDU_CERTIFICATION_TEACHER
-        elsif creator_of_game?(game)
-          User::EDU_GAME_MANAGER
-        elsif is_teacher?
-          User::EDU_TEACHER
-        else
-          User::EDU_NORMAL
-        end
-    return @identity
-  end
-
-  # 我的实训
-  def my_shixuns
-    shixun_ids = shixun_members.pluck(:shixun_id) + myshixuns.pluck(:shixun_id)
-    Shixun.where(:id => shixun_ids).visible
-  end
-
-  # 用户是否有权限查看实训
-  # 1、实训删除只有管理员能看到
-  # 2、实训隐藏了只有管理员、实训合作者能看到
-  # 3、如果有限制学校范围,则学校的用户、管理员、实训合作者能看到
-  def shixun_permission(shixun)
-    case shixun.status
-    when -1 # 软删除只有管理员能访问
-      admin?
-    when 0, 1, 3 # 申请发布或者已关闭的实训,只有实训管理员可以访问
-      manager_of_shixun?(shixun)
-    when 2
-      if shixun.hidden
-        manager_of_shixun?(shixun)
-      else
-        shixun.use_scope == 0  || manager_of_shixun?(shixun) || shixun.shixun_schools.exists?(school_id: school_id)
-      end
-    end
-  end
-
-  # 用户在平台名称的显示方式
-  def full_name
-    return '游客' unless logged?
-
-    name = show_realname? ? lastname + firstname : nickname
-    name.blank? ? (nickname.blank? ? login : nickname) : name
-  end
-
-  # 用户的真实姓名(不考虑用户是否隐藏了真实姓名,课堂模块都用真实姓名)
-  def real_name
-    return '游客' unless logged?
-    name = lastname + firstname
-    name = name.blank? ? (nickname.blank? ? login : nickname) : name
-    name.gsub(/\s+/, '').strip    #6.11 -hs
-  end
-
-  def only_real_name
-    "#{lastname}#{firstname}"
-  end
-
-  # 用户是否选题毕设课题
-  def selected_topic?(topic)
-    student_graduation_topics.where(graduation_topic_id: topic.id).last.try(:status)
-  end
-
-  def click_time
-    click_time = OnclickTime.find_by(user_id: id) || OnclickTime.create(user_id: id, onclick_time: created_on)
-    click_time.onclick_time
-  end
-
-  def manager_of_memo?(memo)
-    id == memo.author_id || admin? || business?
-  end
-
-  # 是否是项目管理者
-  def manager_of_project?(project)
-    project.project_members.where(user_id: id).count > 0
-  end
-
-  def logged?
-    true
-  end
-
-  def active?
-    status == STATUS_ACTIVE
-  end
-
-  def locked?
-    status == STATUS_LOCKED
-  end
-
-  def phone_binded?
-    phone.present?
-  end
-
-  def self.current=(user)
-    Thread.current[:current_user] = user
-  end
-
-  def self.current
-    Thread.current[:current_user] ||= User.anonymous
-  end
-
-  def self.anonymous
-    anonymous_user = AnonymousUser.unscoped.take
-    if anonymous_user.nil?
-      anonymous_user = AnonymousUser.unscoped.create(lastname: 'Anonymous', firstname: '', login: '',
-                                                     mail: '358551897@qq.com', phone: '13333333333', status: 0)
-      raise "Unable to create the anonymous user: error_info:#{anonymous_user.errors.messages}" if anonymous_user.new_record?
-    end
-    anonymous_user
-  end
-
-  # Returns the user who matches the given autologin +key+ or nil
-  def self.try_to_autologin(key)
-    user = Token.find_active_user('autologin', key)
-    user.update(last_login_on: Time.now) if user
-    user
-  end
-
-  def self.hash_password(clear_password)
-    Digest::SHA1.hexdigest(clear_password || "")
-  end
-
-  def check_password?(clear_password)
-    # Preventing Timing Attack
-    ActiveSupport::SecurityUtils.secure_compare(
-      User.hash_password("#{salt}#{User.hash_password clear_password}"),
-      hashed_password
-    )
-  end
-
-  # 工程认证的学校
-  def ec_school
-    school_id = self.ec_school_users.pluck(:school_id).first ||
-        self.ec_major_schools.pluck(:school_id).first ||
-        (self.ec_course_users.first && self.ec_course_users.first.try(:ec_course).try(:ec_year).try(:ec_major_school).try(:school_id))
-  end
-
-  # 登录,返回用户名与密码匹配的用户
-  def self.try_to_login(login, password)
-    login = login.to_s.strip
-    password = password.to_s
-
-    # Make sure no one can sign in with an empty login or password
-    return nil if login.empty? || password.empty?
-    if (login =~ VALID_EMAIL_REGEX)
-      user = find_by_mail(login)
-    elsif (login =~ VALID_PHONE_REGEX)
-      user = find_by_phone(login)
-    else
-      user = find_by_login(login)
-    end
-
-    user
-  rescue => text
-    raise text
-  end
-
-  def show_real_name
-    name = lastname + firstname
-    if name.blank?
-      nickname.blank? ? login : nickname
-    else
-      name
-    end
-  end
-
-  def update_hashed_password
-    if password
-      salt_password(password)
-    end
-  end
-
-  def salt_password(clear_password)
-    self.salt = User.generate_salt
-    self.hashed_password = User.hash_password("#{salt}#{User.hash_password clear_password}")
-  end
-
-  def self.generate_salt
-    Educoder::Utils.random_hex(16)
-  end
-
-  # 全部已认证
-  def all_certified?
-    authentication? && professional_certification?
-  end
-
-  # 是否绑定邮箱
-  def email_binded?
-    mail.present?
-  end
-
-  # 学院的url标识
-  def college_identifier
-    Department.find_by_id(department_members.pluck(:department_id).first)&.identifier
-  end
-
-  # 是否能申请试用
-  def can_apply_trial?
-    return false if certification == 1
-
-    apply = ApplyAction.order(created_at: :desc).find_by(user_id: id, container_type: 'TrialAuthorization')
-
-    apply.present? && !apply.status.zero?
-  end
-
-  # 是否已经签到
-  def attendance_signed?
-    attendance = Attendance.find_by(user_id: id)
-
-    attendance.present? && Util.days_between(Time.zone.now, attendance.created_at).zero?
-  end
-
-  # 明日签到金币
-  def tomorrow_attendance_gold
-    Attendance.find_by(user_id: id)&.next_gold || 60  # 基础50,连续签到+10
-  end
-
-  def admin_or_business?
-    admin? || business?
-  end
-
-  # 149课程的评审用户数据创建(包含创建课堂学生)
-  def open_class_user
-    user = User.find_by(login: "OpenClassUser")
-    unless user
-      ActiveRecord::Base.transaction do
-        user_params = {status: 1, login: "OpenClassUser", lastname: "开放课程",
-                       nickname: "开放课程", professional_certification: 1, certification: 1, grade: 0,
-                       password: "12345678", phone: "11122223333", profile_completed: 1}
-        user = User.create!(user_params)
-
-        UserExtension.create!(user_id: user.id, gender: 0, school_id: 117, :identity => 1, :student_id => "openclassuser")
-
-        subject = Subject.find_by(id: 149)
-        if subject
-          subject.courses.each do |course|
-            CourseMember.create!(course_id: course.id, role: 4, user_id: user.id) if !course.course_students.exists?(user_id: user.id)
-          end
-        end
-      end
-    end
-    user
-  end
-
-  protected
-  def validate_password_length
-    # 管理员的初始密码是5位
-    if password.present? && password.size < MIX_PASSWORD_LIMIT && !User.current.admin?
-      raise("密码长度不能低于#{MIX_PASSWORD_LIMIT}位")
-    end
-  end
-end
-
-
-class AnonymousUser < User
-  validate :validate_anonymous_uniqueness, :on => :create
-
-  def validate_anonymous_uniqueness
-    # There should be only one AnonymousUser in the database
-    errors.add :base, 'An anonymous user already exists.' if AnonymousUser.exists?
-  end
-
-  def available_custom_fields
-    []
-  end
-
-  # Overrides a few properties
-  def logged?; false end
-  def admin; false end
-  def name(*args); I18n.t(:label_user_anonymous) end
-  # def mail=(*args); nil end
-  # def mail; nil end
-  def time_zone; nil end
-  def rss_key; nil end
-
-
-  def membership(*args)
-    nil
-  end
-
-  def member_of?(*args)
-    false
-  end
-
-  # Anonymous user can not be destroyed
-  def destroy
-    false
-  end
-
-  protected
-
-  def instantiate_email_address
-  end
-
-end
+class User < ApplicationRecord
+  include Watchable
+  include Searchable::Dependents::User
+
+  # Account statuses
+  STATUS_ANONYMOUS  = 0
+  STATUS_ACTIVE     = 1
+  STATUS_REGISTERED = 2
+  STATUS_LOCKED     = 3
+
+  # tpi tpm权限控制
+  EDU_ADMIN = 1       # 超级管理员
+  EDU_BUSINESS = 2    # 运营人员
+  EDU_SHIXUN_MANAGER = 3 # 实训管理员
+  EDU_SHIXUN_MEMBER = 4  # 实训成员
+  EDU_CERTIFICATION_TEACHER = 5 # 平台认证的老师
+  EDU_GAME_MANAGER = 6     # TPI的创建者
+  EDU_TEACHER = 7 # 平台老师,但是未认证
+  EDU_NORMAL = 8  # 普通用户
+
+  VALID_EMAIL_REGEX = /^[a-zA-Z0-9]+([.\-_\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/i
+  VALID_PHONE_REGEX = /^1\d{10}$/
+
+  LOGIN_LENGTH_LIMIT = 30
+  MAIL_LENGTH_LMIT = 60
+
+  MIX_PASSWORD_LIMIT = 8
+
+  has_one :user_extension, dependent: :destroy
+  accepts_nested_attributes_for :user_extension, update_only: true
+
+  has_many :memos, foreign_key: 'author_id'
+  has_many :created_shixuns, class_name: 'Shixun'
+  has_many :shixun_members, :dependent => :destroy
+  has_many :shixuns, :through => :shixun_members
+  has_many :myshixuns, :dependent => :destroy
+  has_many :study_shixuns, through: :myshixuns, source: :shixun   # 已学习的实训
+  has_many :course_messages
+  has_many :courses, dependent: :destroy
+
+  #试卷
+  has_many :exercise_banks, :dependent => :destroy
+  has_many :exercise_users, :dependent => :destroy
+  has_many :exercise_answers, :dependent => :destroy  #针对每个题目学生的答案
+  has_many :exercise_shixun_answers, :dependent => :destroy  #针对每个实训题目学生的答案
+  has_many :exercise_answer_comments, :dependent => :destroy
+  has_many :exercises, :dependent => :destroy  #创建的试卷
+
+  has_many :homework_banks, dependent: :destroy
+
+  has_many :graduation_works, dependent: :destroy
+
+  has_many :students_for_courses, foreign_key: :student_id, dependent: :destroy
+  has_one :onclick_time, :dependent => :destroy
+
+  # 新版私信
+  has_many :private_messages, dependent: :destroy
+  has_many :recent_contacts, through: :private_messages, source: :target
+  has_many :tidings, :dependent => :destroy
+
+  has_many :games, :dependent => :destroy
+  has_many :created_subjects, foreign_key: :user_id, class_name: 'Subject'
+  has_many :subject_members, :dependent => :destroy
+  has_many :subjects, :through => :subject_members
+  has_many :grades, :dependent => :destroy
+  has_many :experiences, :dependent => :destroy
+  has_many :student_works, :dependent => :destroy
+  has_many :student_works_scores
+  has_many :student_works_evaluation_distributions
+
+  # 毕业设计
+  has_many :graduation_topics, :dependent => :destroy
+  has_many :student_graduation_topics, :dependent => :destroy
+
+  # 题库
+  has_many :question_banks, :dependent => :destroy
+  # 毕设任务题库
+  has_many :gtask_banks, dependent: :destroy
+  has_many :gtopic_banks, dependent: :destroy
+
+  #问卷
+  has_many :course_members, :dependent => :destroy
+  has_many :poll_votes, :dependent => :destroy
+  has_many :poll_users, :dependent => :destroy
+
+  has_many :messages,foreign_key: 'author_id',:dependent => :destroy
+
+  has_many :journals_for_messages, :as => :jour, :dependent => :destroy
+  has_many :teacher_course_groups, :dependent => :destroy
+
+  has_many :attachments,foreign_key: :author_id, :dependent => :destroy
+
+  # 工程认证
+  has_many :ec_school_users,:dependent => :destroy
+  has_many :schools, :through => :ec_school_users
+
+  has_many :ec_major_school_users, :dependent => :destroy
+  has_many :ec_major_schools, :through => :ec_major_school_users
+
+  has_many :ec_course_users
+
+  has_many :department_members, dependent: :destroy #部门管理员
+
+  # 课堂
+  has_many :student_course_members, -> { course_students }, class_name: 'CourseMember'
+  has_many :as_student_courses, through: :student_course_members, source: :course
+  has_many :manage_course_members, -> { teachers_and_admin }, class_name: 'CourseMember'
+  has_many :manage_courses, through: :manage_course_members, source: :course
+
+  # 关注
+  has_many :be_watchers, foreign_key: :user_id, dependent: :destroy # 我的关注
+  has_many :be_watcher_users, through: :be_watchers, dependent: :destroy # 我关注的用户
+
+  # 认证
+  has_many :apply_user_authentication
+  has_one :process_real_name_apply, -> { processing.real_name_auth.order(created_at: :desc) }, class_name: 'ApplyUserAuthentication'
+  has_one :process_professional_apply, -> { processing.professional_auth.order(created_at: :desc) }, class_name: 'ApplyUserAuthentication'
+  has_many :apply_actions, dependent: :destroy
+  has_many :trail_auth_apply_actions, -> { where(container_type: 'TrialAuthorization') }, class_name: 'ApplyAction'
+
+  has_many :attendances
+
+  # 兴趣
+  has_many :user_interests, dependent: :delete_all
+  has_many :interests, through: :user_interests, source: :repertoire
+
+  # 众包
+  has_many :project_packages, foreign_key: :creator_id, dependent: :destroy
+  has_many :bidding_users, dependent: :destroy
+  has_many :bidden_project_packages, through: :bidding_users, source: :project_package
+
+  # 项目
+  has_many :applied_projects, dependent: :destroy
+
+  # 教学案例
+  has_many :libraries, dependent: :destroy
+
+  # 视频
+  has_many :videos, dependent: :destroy
+
+  # 客户管理
+  belongs_to :partner, optional: true
+
+  # Groups and active users
+  scope :active, lambda { where(status: STATUS_ACTIVE) }
+
+  attr_accessor :password, :password_confirmation
+
+  delegate :gender, :department_id, :school_id, :location, :location_city, :technical_title, to: :user_extension, allow_nil: true
+
+  before_save :update_hashed_password
+
+  #
+  # validations
+  #
+  validates_presence_of :login, :if => Proc.new { |user| !user.is_a?(AnonymousUser) }, case_sensitive: false
+  validates_uniqueness_of :login, :if => Proc.new { |user| user.login_changed? && user.login.present? }, case_sensitive: false
+  validates_uniqueness_of :mail, :if => Proc.new { |user| user.mail_changed? && user.mail.present? }, case_sensitive: false
+  validates_uniqueness_of :phone, :if => Proc.new { |user| user.phone_changed? && user.phone.present? }, case_sensitive: false
+  validates_length_of :login, maximum: LOGIN_LENGTH_LIMIT
+  validates_length_of :mail, maximum: MAIL_LENGTH_LMIT
+  # validates_format_of :mail, with: VALID_EMAIL_REGEX, multiline: true
+  # validates_format_of :phone, with: VALID_PHONE_REGEX, multiline: true
+  validate :validate_password_length
+
+  # validates :nickname, presence: true, length: { maximum: 10 }
+  # validates :lastname, presence: true
+
+  # 删除自动登录的token,一旦退出下次会提示需要登录
+  def delete_autologin_token(value)
+    Token.where(:user_id => id, :action => 'autologin', :value => value).delete_all
+  end
+
+  def delete_session_token(value)
+    Token.where(:user_id => id, :action => 'session', :value => value).delete_all
+  end
+
+  def git_mail
+    mail.blank? ? "#{login}@educoder.net" : mail
+  end
+
+  # 学号
+  def student_id
+    self.user_extension.try(:student_id)
+  end
+
+  # 关注数
+  def follow_count
+    Watcher.where(user_id: id, watchable_type: %w(Principal User)).count
+    # User.watched_by(id).count
+  end
+
+  # 粉丝数
+  def fan_count
+    Watcher.where(watchable_type: %w(Principal User), watchable_id: id).count
+    # watchers.count
+  end
+
+  # 判断当前用户是否为老师
+  def is_teacher?
+    self.user_extension.teacher?
+  end
+
+  # 平台认证的老师
+  def is_certification_teacher
+    self.user_extension.teacher? && self.professional_certification
+  end
+
+  def certification_teacher?
+    professional_certification? && user_extension.teacher?
+  end
+
+  # 判断用户的身份
+  def identity
+    ue = self.user_extension
+    unless ue.blank?
+      if ue.teacher?
+        ue.technical_title ? ue.technical_title : "老师"
+      elsif ue.student?
+        "学生"
+      else
+        ue.technical_title ? ue.technical_title : "专业人士"
+      end
+    end
+  end
+
+  # 判断当前用户是否通过职业认证
+  def pro_certification?
+    professional_certification
+  end
+
+  # 用户的学校名称
+  def school_name
+    user_extension&.school&.name || ''
+  end
+
+  # 用户的学院名称
+  def department_name
+    user_extension&.department&.name || ''
+  end
+
+  # 课堂的老师(创建者、老师、助教)
+  def teacher_of_course?(course)
+    course.course_members.exists?(user_id: id, role: [1,2,3], is_active: 1) || admin? || business?
+  end
+
+  # 课堂的老师(创建者、老师、助教),不用考虑当前身份
+  def teacher_of_course_non_active?(course)
+    course.course_members.exists?(user_id: id, role: [1,2,3])
+  end
+
+  # 是否是教师,课堂管理员或者超级管理员
+  def teacher_or_admin?(course)
+    course.course_members.exists?(user_id: id, role: [1,2], is_active: 1) || admin? || business?
+  end
+
+  # 课堂的创建者(考虑到多重身份的用户)
+  def creator_of_course?(course)
+    course.course_members.exists?(user_id: id, role: 1, is_active: 1) || admin? || business?
+  end
+
+  # 课堂的学生
+  def student_of_course?(course)
+    course.course_members.exists?(user_id: id, role: %i[STUDENT])
+  end
+
+  # 课堂成员
+  def member_of_course?(course)
+    course&.course_members.exists?(user_id: id)
+  end
+
+  # 实训路径管理员
+  def creator_of_subject?(subject)
+    subject.user_id == id || admin?
+  end
+
+  # 实训路径:合作者、admin
+  def manager_of_subject?(subject)
+    subject.subject_members.exists?(user_id: id, role: [1,2]) || admin?
+  end
+
+  # 实训管理员:实训合作者、admin
+  def manager_of_shixun?(shixun)
+     shixun.shixun_members.exists?(role: [1,2], user_id: id) || admin? || business?
+  end
+
+  # 实训管理员
+  def creator_of_shixun?(shixun)
+    id == shixun.user_id
+  end
+
+  # 实训的合作者
+  def member_of_shixun?(shixun)
+    #self.shixun_members.where(:role => 2, :shixun_id => shixun.id).present?
+    shixun.shixun_members.exists?(role: 2, user_id: id)
+  end
+
+  # TPI的创建者
+  def creator_of_game?(game)
+    id == game.user_id
+  end
+
+  # 用户账号状态
+  def active?
+    status == STATUS_ACTIVE
+  end
+
+  def registered?
+    status == STATUS_REGISTERED
+  end
+
+  def locked?
+    status == STATUS_LOCKED
+  end
+
+  def activate
+    self.status = STATUS_ACTIVE
+  end
+
+  def register
+    self.status = STATUS_REGISTERED
+  end
+
+  def lock
+    self.status = STATUS_LOCKED
+  end
+
+  def activate!
+    update_attribute(:status, STATUS_ACTIVE)
+  end
+
+  def register!
+    update_attribute(:status, STATUS_REGISTERED)
+  end
+
+  def lock!
+    update_attribute(:status, STATUS_LOCKED)
+  end
+
+  # 课程用户身份
+  def course_identity(course)
+    if !logged?
+      Course::Anonymous
+    elsif admin?
+      Course::ADMIN
+    elsif business?
+      Course::BUSINESS
+    else
+      role = course&.course_members&.find_by(user_id: id, is_active: 1)&.role
+      case role
+      when nil                   then Course::NORMAL
+      when 'CREATOR'             then Course::CREATOR
+      when 'PROFESSOR'           then Course::PROFESSOR
+      when 'STUDENT'             then Course::STUDENT
+      when 'ASSISTANT_PROFESSOR' then Course::ASSISTANT_PROFESSOR
+      end
+    end
+  end
+
+  # 实训用户身份
+  def shixun_identity(shixun)
+    @identity =
+        if admin?
+          User::EDU_ADMIN
+        elsif business?
+          User::EDU_BUSINESS
+        elsif creator_of_shixun?(shixun)
+          User::EDU_SHIXUN_MANAGER
+        elsif member_of_shixun?(shixun)
+          User::EDU_SHIXUN_MEMBER
+        elsif is_certification_teacher
+          User::EDU_CERTIFICATION_TEACHER
+        elsif is_teacher?
+          User::EDU_TEACHER
+        else
+          User::EDU_NORMAL
+        end
+    return @identity
+  end
+
+  # tpi的用户身份
+  def game_identity(game)
+    shixun = game.myshixun.shixun
+    @identity =
+        if admin?
+          User::EDU_ADMIN
+        elsif business?
+          User::EDU_BUSINESS
+        elsif creator_of_shixun?(shixun)
+          User::EDU_SHIXUN_MANAGER
+        elsif member_of_shixun?(shixun)
+          User::EDU_SHIXUN_MEMBER
+        elsif is_certification_teacher
+          User::EDU_CERTIFICATION_TEACHER
+        elsif creator_of_game?(game)
+          User::EDU_GAME_MANAGER
+        elsif is_teacher?
+          User::EDU_TEACHER
+        else
+          User::EDU_NORMAL
+        end
+    return @identity
+  end
+
+  # 我的实训
+  def my_shixuns
+    shixun_ids = shixun_members.pluck(:shixun_id) + myshixuns.pluck(:shixun_id)
+    Shixun.where(:id => shixun_ids).visible
+  end
+
+  # 用户是否有权限查看实训
+  # 1、实训删除只有管理员能看到
+  # 2、实训隐藏了只有管理员、实训合作者能看到
+  # 3、如果有限制学校范围,则学校的用户、管理员、实训合作者能看到
+  def shixun_permission(shixun)
+    case shixun.status
+    when -1 # 软删除只有管理员能访问
+      admin?
+    when 0, 1, 3 # 申请发布或者已关闭的实训,只有实训管理员可以访问
+      manager_of_shixun?(shixun)
+    when 2
+      if shixun.hidden
+        manager_of_shixun?(shixun)
+      else
+        shixun.use_scope == 0  || manager_of_shixun?(shixun) || shixun.shixun_schools.exists?(school_id: school_id)
+      end
+    end
+  end
+
+  # 用户在平台名称的显示方式
+  def full_name
+    return '游客' unless logged?
+
+    name = show_realname? ? lastname + firstname : nickname
+    name.blank? ? (nickname.blank? ? login : nickname) : name
+  end
+
+  # 用户的真实姓名(不考虑用户是否隐藏了真实姓名,课堂模块都用真实姓名)
+  def real_name
+    return '游客' unless logged?
+    name = lastname + firstname
+    name = name.blank? ? (nickname.blank? ? login : nickname) : name
+    name.gsub(/\s+/, '').strip    #6.11 -hs
+  end
+
+  def only_real_name
+    "#{lastname}#{firstname}"
+  end
+
+  # 用户是否选题毕设课题
+  def selected_topic?(topic)
+    student_graduation_topics.where(graduation_topic_id: topic.id).last.try(:status)
+  end
+
+  def click_time
+    click_time = OnclickTime.find_by(user_id: id) || OnclickTime.create(user_id: id, onclick_time: created_on)
+    click_time.onclick_time
+  end
+
+  def manager_of_memo?(memo)
+    id == memo.author_id || admin? || business?
+  end
+
+  # 是否是项目管理者
+  def manager_of_project?(project)
+    project.project_members.where(user_id: id).count > 0
+  end
+
+  def logged?
+    true
+  end
+
+  def active?
+    status == STATUS_ACTIVE
+  end
+
+  def locked?
+    status == STATUS_LOCKED
+  end
+
+  def phone_binded?
+    phone.present?
+  end
+
+  def self.current=(user)
+    Thread.current[:current_user] = user
+  end
+
+  def self.current
+    Thread.current[:current_user] ||= User.anonymous
+  end
+
+  def self.anonymous
+    anonymous_user = AnonymousUser.unscoped.take
+    if anonymous_user.nil?
+      anonymous_user = AnonymousUser.unscoped.create(lastname: 'Anonymous', firstname: '', login: '',
+                                                     mail: '358551897@qq.com', phone: '13333333333', status: 0)
+      raise "Unable to create the anonymous user: error_info:#{anonymous_user.errors.messages}" if anonymous_user.new_record?
+    end
+    anonymous_user
+  end
+
+  # Returns the user who matches the given autologin +key+ or nil
+  def self.try_to_autologin(key)
+    user = Token.find_active_user('autologin', key)
+    user.update(last_login_on: Time.now) if user
+    user
+  end
+
+  def self.hash_password(clear_password)
+    Digest::SHA1.hexdigest(clear_password || "")
+  end
+
+  def check_password?(clear_password)
+    # Preventing Timing Attack
+    ActiveSupport::SecurityUtils.secure_compare(
+      User.hash_password("#{salt}#{User.hash_password clear_password}"),
+      hashed_password
+    )
+  end
+
+  # 工程认证的学校
+  def ec_school
+    school_id = self.ec_school_users.pluck(:school_id).first ||
+        self.ec_major_schools.pluck(:school_id).first ||
+        (self.ec_course_users.first && self.ec_course_users.first.try(:ec_course).try(:ec_year).try(:ec_major_school).try(:school_id))
+  end
+
+  # 登录,返回用户名与密码匹配的用户
+  def self.try_to_login(login, password)
+    login = login.to_s.strip
+    password = password.to_s
+
+    # Make sure no one can sign in with an empty login or password
+    return nil if login.empty? || password.empty?
+    if (login =~ VALID_EMAIL_REGEX)
+      user = find_by_mail(login)
+    elsif (login =~ VALID_PHONE_REGEX)
+      user = find_by_phone(login)
+    else
+      user = find_by_login(login)
+    end
+
+    user
+  rescue => text
+    raise text
+  end
+
+  def show_real_name
+    name = lastname + firstname
+    if name.blank?
+      nickname.blank? ? login : nickname
+    else
+      name
+    end
+  end
+
+  def update_hashed_password
+    if password
+      salt_password(password)
+    end
+  end
+
+  def salt_password(clear_password)
+    self.salt = User.generate_salt
+    self.hashed_password = User.hash_password("#{salt}#{User.hash_password clear_password}")
+  end
+
+  def self.generate_salt
+    Educoder::Utils.random_hex(16)
+  end
+
+  # 全部已认证
+  def all_certified?
+    authentication? && professional_certification?
+  end
+
+  # 是否绑定邮箱
+  def email_binded?
+    mail.present?
+  end
+
+  # 学院的url标识
+  def college_identifier
+    Department.find_by_id(department_members.pluck(:department_id).first)&.identifier
+  end
+
+  # 是否能申请试用
+  def can_apply_trial?
+    return false if certification == 1
+
+    apply = ApplyAction.order(created_at: :desc).find_by(user_id: id, container_type: 'TrialAuthorization')
+
+    apply.present? && !apply.status.zero?
+  end
+
+  # 是否已经签到
+  def attendance_signed?
+    attendance = Attendance.find_by(user_id: id)
+
+    attendance.present? && Util.days_between(Time.zone.now, attendance.created_at).zero?
+  end
+
+  # 明日签到金币
+  def tomorrow_attendance_gold
+    Attendance.find_by(user_id: id)&.next_gold || 60  # 基础50,连续签到+10
+  end
+
+  def admin_or_business?
+    admin? || business?
+  end
+
+  protected
+  def validate_password_length
+    # 管理员的初始密码是5位
+    if password.present? && password.size < MIX_PASSWORD_LIMIT && !User.current.admin?
+      raise("密码长度不能低于#{MIX_PASSWORD_LIMIT}位")
+    end
+  end
+end
+
+
+class AnonymousUser < User
+  validate :validate_anonymous_uniqueness, :on => :create
+
+  def validate_anonymous_uniqueness
+    # There should be only one AnonymousUser in the database
+    errors.add :base, 'An anonymous user already exists.' if AnonymousUser.exists?
+  end
+
+  def available_custom_fields
+    []
+  end
+
+  # Overrides a few properties
+  def logged?; false end
+  def admin; false end
+  def name(*args); I18n.t(:label_user_anonymous) end
+  # def mail=(*args); nil end
+  # def mail; nil end
+  def time_zone; nil end
+  def rss_key; nil end
+
+
+  def membership(*args)
+    nil
+  end
+
+  def member_of?(*args)
+    false
+  end
+
+  # Anonymous user can not be destroyed
+  def destroy
+    false
+  end
+
+  protected
+
+  def instantiate_email_address
+  end
+
+end
diff --git a/app/services/ecs/import_student_service.rb b/app/services/ecs/import_student_service.rb
index 9014e221c..f5cd7c6ac 100644
--- a/app/services/ecs/import_student_service.rb
+++ b/app/services/ecs/import_student_service.rb
@@ -1,21 +1,20 @@
 class Ecs::ImportStudentService < ApplicationService
   Error = Class.new(StandardError)
 
-  attr_reader :ec_year, :attachment
+  attr_reader :ec_year, :params
 
-  def initialize(ec_year, attachment_id)
-    @ec_year    = ec_year
-    @attachment = Attachment.find_by(id: attachment_id)
+  def initialize(ec_year, params)
+    @ec_year = ec_year
+    @params  = params
   end
 
   def call
-    raise Error, '文件不存在' if attachment.blank?
+    raise Error, '文件不存在' if params[:file].blank? || !params[:file].is_a?(ActionDispatch::Http::UploadedFile)
 
-    path = attachment.diskfile
-    excel = Ecs::ImportStudentExcel.new(path)
+    excel = Ecs::ImportStudentExcel.new(params[:file].path)
 
     success_count = 0
-    EcYearStudent.bulk_insert(:student_id, :name, :created_at, :updated_at) do |worker|
+    EcYearStudent.bulk_insert(:ec_year_id, :student_id, :name, :created_at, :updated_at) do |worker|
       excel.read_each do |student_id, name|
         success_count += 1
 
@@ -25,7 +24,7 @@ class Ecs::ImportStudentService < ApplicationService
           next
         end
 
-        worker.add(student_id: student_id, name: name)
+        worker.add(ec_year_id: ec_year.id, student_id: student_id, name: name)
       end
     end
 
diff --git a/app/services/ecs/save_graduation_course_supports_service.rb b/app/services/ecs/save_graduation_course_supports_service.rb
index bfbdb997f..de4ecc71a 100644
--- a/app/services/ecs/save_graduation_course_supports_service.rb
+++ b/app/services/ecs/save_graduation_course_supports_service.rb
@@ -9,6 +9,8 @@ class Ecs::SaveGraduationCourseSupportsService < ApplicationService
   end
 
   def call
+    set_course_supports_position!
+
     Ecs::SaveGraduationCourseSupportForm.new(params).validate!
 
     accepts_attributes = build_accepts_nested_attributes(
@@ -20,4 +22,10 @@ class Ecs::SaveGraduationCourseSupportsService < ApplicationService
     graduation_subitem.save!
     graduation_subitem
   end
+
+  def set_course_supports_position!
+    params[:course_supports].each_with_index do |item, index|
+      item[:position] = index + 1
+    end
+  end
 end
\ No newline at end of file
diff --git a/app/tasks/statistic_school_daily_report_task.rb b/app/tasks/statistic_school_daily_report_task.rb
index 5cd3fda7c..794a4b573 100644
--- a/app/tasks/statistic_school_daily_report_task.rb
+++ b/app/tasks/statistic_school_daily_report_task.rb
@@ -27,8 +27,8 @@ class StatisticSchoolDailyReportTask
       # 新增实训评测数量
       shixun_evaluate_count = EvaluateRecord.joins('LEFT JOIN homework_commons_shixuns hcs ON hcs.shixun_id = evaluate_records.shixun_id')
                                 .joins('LEFT JOIN homework_commons hc ON hcs.homework_common_id = hc.id AND hc.homework_type = 4')
-                                .joins('LEFT JOIN members ON members.user_id = evaluate_records.user_id')
-                                .joins('LEFT JOIN courses ON members.course_id = courses.id AND hc.course_id = courses.id')
+                                .joins('LEFT JOIN course_members ON course_members.user_id = evaluate_records.user_id')
+                                .joins('LEFT JOIN courses ON course_members.course_id = courses.id AND hc.course_id = courses.id')
                                 .where(courses: { school_id: school.id })
                                 .where(created_at: yesterday).reorder(nil).count
 
diff --git a/app/tasks/statistic_school_report_task.rb b/app/tasks/statistic_school_report_task.rb
index a55eb7a42..a72c57830 100644
--- a/app/tasks/statistic_school_report_task.rb
+++ b/app/tasks/statistic_school_report_task.rb
@@ -2,10 +2,10 @@ class StatisticSchoolReportTask
   def call
     School.find_each do |school|
       evaluate_count = Game.joins(:challenge)
-                           .joins('LEFT JOIN members ON members.user_id = games.user_id')
+                           .joins('LEFT JOIN course_members ON course_members.user_id = games.user_id')
                            .joins('LEFT JOIN homework_commons_shixuns hcs ON hcs.shixun_id = challenges.shixun_id')
                            .joins('LEFT JOIN homework_commons hc ON hcs.homework_common_id = hc.id AND hc.homework_type = 4')
-                           .joins('LEFT JOIN courses ON hc.course_id = courses.id AND members.course_id = courses.id')
+                           .joins('LEFT JOIN courses ON hc.course_id = courses.id AND course_members.course_id = courses.id')
                            .where(courses: { school_id: school.id })
                            .sum(:evaluate_count)
 
diff --git a/app/views/admins/professional_authentications/shared/_list.html.erb b/app/views/admins/professional_authentications/shared/_list.html.erb
index fd7685f98..10934a702 100644
--- a/app/views/admins/professional_authentications/shared/_list.html.erb
+++ b/app/views/admins/professional_authentications/shared/_list.html.erb
@@ -53,12 +53,12 @@
           <td><span class="apply-status-<%= apply.status %>"><%= apply.status_text %></span></td>
         <% else %>
           <td class="action-container">
-            <%= agree_link '同意', agree_admins_professional_authentication_path(apply, element: ".professional-authentication-#{apply.id}"), 'data-confirm': '确认审核通过?' %>
+            <%= agree_link '同意', agree_admins_professional_authentication_path(apply, element: ".professional-authentication-#{apply.id}"), 'data-confirm': '确认审核通过?', 'data-disable-with': "提交中..." %>
             <%= javascript_void_link('拒绝', class: 'action refuse-action',
                                      data: {
                                          toggle: 'modal', target: '.admin-common-refuse-modal', id: apply.id,
                                          url: refuse_admins_professional_authentication_path(apply, element: ".professional-authentication-#{apply.id}")
-                                     }) %>
+                                     }, 'data-disable-with': "拒绝中...") %>
           </td>
         <% end %>
       </tr>
diff --git a/app/views/ecs/graduation_course_supports/show.xlsx.axlsx b/app/views/ecs/graduation_course_supports/show.xlsx.axlsx
index e2c2599ec..ae81d931b 100644
--- a/app/views/ecs/graduation_course_supports/show.xlsx.axlsx
+++ b/app/views/ecs/graduation_course_supports/show.xlsx.axlsx
@@ -9,13 +9,13 @@ wb = xlsx_package.workbook
 wb.styles do |style|
   title_style = style.add_style(sz: 16, height: 20, b: true)
   ec_year_style = style.add_style(sz: 10, height: 14)
-  label_style = style.add_style(sz: 11, b: true, bg_color: '90EE90', alignment: { horizontal: :center }, border: { style: :thin, color: '000000' })
+  label_style = style.add_style(sz: 11, b: true, bg_color: '90EE90', alignment: { horizontal: :center, vertical: :center }, border: { style: :thin, color: '000000' })
   content_style = style.add_style(sz: 11, height: 16, border: { style: :thin, color: '000000' })
-  tip_style = style.add_style(sz: 11, height: 16, color: 'FFA07A')
+  tip_style = style.add_style(sz: 11, height: 16, color: Axlsx::Color.new(rgb: 'FFFFA07A'))
 
   wb.add_worksheet(:name => '课程体系对毕业要求的支撑') do |sheet|
     sheet.add_row ['课程体系VS毕业要求'], style: title_style
-    sheet.merge_cells wb.rows.first.cells[(1..(3 + max_support_length - 1))]
+    sheet.merge_cells sheet.rows.first.cells[(1..(3 + max_support_length - 1))]
 
     sheet.add_row []
 
@@ -25,8 +25,8 @@ wb.styles do |style|
 
     sheet.add_row ['注:有对应关系的课程名称下方为其权重系数,一个指标点的权重系数之和必须等于1'], style: tip_style
     sheet.add_row ['注:“★” 表示关联度高']
-    sheet.merge_cells wb.rows[5].cells[(1..(3 + max_support_length - 1))]
-    sheet.merge_cells wb.rows[6].cells[(1..(3 + max_support_length - 1))]
+    sheet.merge_cells sheet.rows[5].cells[(1..(3 + max_support_length - 1))]
+    sheet.merge_cells sheet.rows[6].cells[(1..(3 + max_support_length - 1))]
 
     sheet.add_row []
 
@@ -34,9 +34,9 @@ wb.styles do |style|
     data[last_column_index] = '课程数量'
     sheet.add_row data, style: label_style
     course_columns = max_support_length.times.map { |i| "课程#{i + 1}" }
-    sheet.add_row %w('一级 二级') + course_columns + ['∑目标值'], style: label_style
+    sheet.add_row %w(一级 二级) + course_columns + ['∑目标值'], style: label_style
     sheet.merge_cells("A9:B9")
-    sheet.merge_cells wb.rows[8].cells[(3..(3 + max_support_length - 1))]
+    # sheet.merge_cells sheet.rows[8].cells[(3..(3 + max_support_length - 1))]
 
     current_row = 11
     graduation_subitems.group_by(&:ec_graduation_requirement).each do |requirement, items|
@@ -61,11 +61,11 @@ wb.styles do |style|
         sheet.add_row course_data, style: styles
         sheet.add_row weight_data, style: styles
 
-        sheet.merge_cells("B#{current_row - 1}:B#{current_row}")
+        sheet.merge_cells("B#{current_row}:B#{current_row + 1}")
         current_row += 2
       end
 
-      sheet.merge_cells("A#{start_row - 1}:B#{current_row - 1}")
+      sheet.merge_cells("A#{start_row}:A#{current_row - 1}")
     end
   end
 end
\ No newline at end of file
diff --git a/app/views/student_works/show.json.jbuilder b/app/views/student_works/show.json.jbuilder
index 192e4d8ec..9bafbe93e 100644
--- a/app/views/student_works/show.json.jbuilder
+++ b/app/views/student_works/show.json.jbuilder
@@ -11,7 +11,7 @@ json.update_user_name @is_evaluation ? "匿名" : @work.update_user.try(:real_na
 json.update_atta @homework.late_duration && @is_author
 
 json.attachments @attachments do |atta|
-  json.partial! "attachments/attachment_simple", locals: {attachment: atta, delete: @work.delete_atta(atta)}
+  json.partial! "attachments/attachment_simple", locals: {attachment: atta, delete: false}
 end
 
 unless @is_evaluation
diff --git a/db/migrate/20190920073337_migrate_user_extension_index.rb b/db/migrate/20190920073337_migrate_user_extension_index.rb
new file mode 100644
index 000000000..1d333bd99
--- /dev/null
+++ b/db/migrate/20190920073337_migrate_user_extension_index.rb
@@ -0,0 +1,6 @@
+class MigrateUserExtensionIndex < ActiveRecord::Migration[5.2]
+  def change
+    remove_index :user_extensions, :school_id
+    add_index :user_extensions, [:school_id, :user_id]
+  end
+end
diff --git a/public/editormd/lib/marked.min.js b/public/editormd/lib/marked.min.js
index 6f14c6e7c..1cd7c2bae 100644
--- a/public/editormd/lib/marked.min.js
+++ b/public/editormd/lib/marked.min.js
@@ -12,5 +12,7 @@
  */
 // 0.4.0  /^ *(#{1,6}) ——》/^ *(#{1,6})   去掉了一个空格 TODO 行内公式带_
 /*if("string"!=typeof e)throw new Error("marked(): input parameter is of type "+Object.prototype.toString.call(e)+", string expected");*/
-!function(e){"use strict";var t={newline:/^\n+/,code:/^( {4}[^\n]+\n*)+/,fences:d,hr:/^ {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\* *){3,})(?:\n+|$)/,heading:/^ *(#{1,6})*([^\n]+?) *(?:#+ *)?(?:\n+|$)/,nptable:d,blockquote:/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,list:/^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,html:"^ {0,3}(?:<(script|pre|style)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?\\?>\\n*|<![A-Z][\\s\\S]*?>\\n*|<!\\[CDATA\\[[\\s\\S]*?\\]\\]>\\n*|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:\\n{2,}|$)|<(?!script|pre|style)([a-z][\\w-]*)(?:attribute)*? */?>(?=\\h*\\n)[\\s\\S]*?(?:\\n{2,}|$)|</(?!script|pre|style)[a-z][\\w-]*\\s*>(?=\\h*\\n)[\\s\\S]*?(?:\\n{2,}|$))",def:/^ {0,3}\[(label)\]: *\n? *<?([^\s>]+)>?(?:(?: +\n? *| *\n *)(title))? *(?:\n+|$)/,table:d,lheading:/^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,paragraph:/^([^\n]+(?:\n(?!hr|heading|lheading| {0,3}>|<\/?(?:tag)(?: +|\n|\/?>)|<(?:script|pre|style|!--))[^\n]+)*)/,text:/^[^\n]+/};function n(e){this.tokens=[],this.tokens.links={},this.options=e||m.defaults,this.rules=t.normal,this.options.pedantic?this.rules=t.pedantic:this.options.gfm&&(this.options.tables?this.rules=t.tables:this.rules=t.gfm)}t._label=/(?!\s*\])(?:\\[\[\]]|[^\[\]])+/,t._title=/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/,t.def=p(t.def).replace("label",t._label).replace("title",t._title).getRegex(),t.bullet=/(?:[*+-]|\d+\.)/,t.item=/^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/,t.item=p(t.item,"gm").replace(/bull/g,t.bullet).getRegex(),t.list=p(t.list).replace(/bull/g,t.bullet).replace("hr","\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))").replace("def","\\n+(?="+t.def.source+")").getRegex(),t._tag="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",t._comment=/<!--(?!-?>)[\s\S]*?-->/,t.html=p(t.html,"i").replace("comment",t._comment).replace("tag",t._tag).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),t.paragraph=p(t.paragraph).replace("hr",t.hr).replace("heading",t.heading).replace("lheading",t.lheading).replace("tag",t._tag).getRegex(),t.blockquote=p(t.blockquote).replace("paragraph",t.paragraph).getRegex(),t.normal=f({},t),t.gfm=f({},t.normal,{fences:/^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\n? *\1 *(?:\n+|$)/,paragraph:/^/,heading:/^ *(#{1,6})+([^\n]+?) *#* *(?:\n+|$)/}),t.gfm.paragraph=p(t.paragraph).replace("(?!","(?!"+t.gfm.fences.source.replace("\\1","\\2")+"|"+t.list.source.replace("\\1","\\3")+"|").getRegex(),t.tables=f({},t.gfm,{nptable:/^ *([^|\n ].*\|.*)\n *([-:]+ *\|[-| :]*)(?:\n((?:.*[^>\n ].*(?:\n|$))*)\n*|$)/,table:/^ *\|(.+)\n *\|?( *[-:]+[-| :]*)(?:\n((?: *[^>\n ].*(?:\n|$))*)\n*|$)/}),t.pedantic=f({},t.normal,{html:p("^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:\"[^\"]*\"|'[^']*'|\\s[^'\"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))").replace("comment",t._comment).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/}),n.rules=t,n.lex=function(e,t){return new n(t).lex(e)},n.prototype.lex=function(e){return e=e.replace(/\r\n|\r/g,"\n").replace(/\t/g,"    ").replace(/\u00a0/g," ").replace(/\u2424/g,"\n"),this.token(e,!0)},n.prototype.token=function(e,n){var r,s,i,l,o,a,h,p,u,c,g,d,f;for(e=e.replace(/^ +$/gm,"");e;)if((i=this.rules.newline.exec(e))&&(e=e.substring(i[0].length),i[0].length>1&&this.tokens.push({type:"space"})),i=this.rules.code.exec(e))e=e.substring(i[0].length),i=i[0].replace(/^ {4}/gm,""),this.tokens.push({type:"code",text:this.options.pedantic?i:i.replace(/\n+$/,"")});else if(i=this.rules.fences.exec(e))e=e.substring(i[0].length),this.tokens.push({type:"code",lang:i[2],text:i[3]||""});else if(i=this.rules.heading.exec(e))e=e.substring(i[0].length),this.tokens.push({type:"heading",depth:i[1].length,text:i[2]});else if(n&&(i=this.rules.nptable.exec(e))&&(a={type:"table",header:b(i[1].replace(/^ *| *\| *$/g,"")),align:i[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:i[3]?i[3].replace(/\n$/,"").split("\n"):[]}).header.length===a.align.length){for(e=e.substring(i[0].length),p=0;p<a.align.length;p++)/^ *-+: *$/.test(a.align[p])?a.align[p]="right":/^ *:-+: *$/.test(a.align[p])?a.align[p]="center":/^ *:-+ *$/.test(a.align[p])?a.align[p]="left":a.align[p]=null;for(p=0;p<a.cells.length;p++)a.cells[p]=b(a.cells[p],a.header.length);this.tokens.push(a)}else if(i=this.rules.hr.exec(e))e=e.substring(i[0].length),this.tokens.push({type:"hr"});else if(i=this.rules.blockquote.exec(e))e=e.substring(i[0].length),this.tokens.push({type:"blockquote_start"}),i=i[0].replace(/^ *> ?/gm,""),this.token(i,n),this.tokens.push({type:"blockquote_end"});else if(i=this.rules.list.exec(e)){for(e=e.substring(i[0].length),g=(l=i[2]).length>1,this.tokens.push({type:"list_start",ordered:g,start:g?+l:""}),r=!1,c=(i=i[0].match(this.rules.item)).length,p=0;p<c;p++)h=(a=i[p]).length,~(a=a.replace(/^ *([*+-]|\d+\.) +/,"")).indexOf("\n ")&&(h-=a.length,a=this.options.pedantic?a.replace(/^ {1,4}/gm,""):a.replace(new RegExp("^ {1,"+h+"}","gm"),"")),this.options.smartLists&&p!==c-1&&(l===(o=t.bullet.exec(i[p+1])[0])||l.length>1&&o.length>1||(e=i.slice(p+1).join("\n")+e,p=c-1)),s=r||/\n\n(?!\s*$)/.test(a),p!==c-1&&(r="\n"===a.charAt(a.length-1),s||(s=r)),f=void 0,(d=/^\[[ xX]\] /.test(a))&&(f=" "!==a[1],a=a.replace(/^\[[ xX]\] +/,"")),this.tokens.push({type:s?"loose_item_start":"list_item_start",task:d,checked:f}),this.token(a,!1),this.tokens.push({type:"list_item_end"});this.tokens.push({type:"list_end"})}else if(i=this.rules.html.exec(e))e=e.substring(i[0].length),this.tokens.push({type:this.options.sanitize?"paragraph":"html",pre:!this.options.sanitizer&&("pre"===i[1]||"script"===i[1]||"style"===i[1]),text:i[0]});else if(n&&(i=this.rules.def.exec(e)))e=e.substring(i[0].length),i[3]&&(i[3]=i[3].substring(1,i[3].length-1)),u=i[1].toLowerCase().replace(/\s+/g," "),this.tokens.links[u]||(this.tokens.links[u]={href:i[2],title:i[3]});else if(n&&(i=this.rules.table.exec(e))&&(a={type:"table",header:b(i[1].replace(/^ *| *\| *$/g,"")),align:i[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:i[3]?i[3].replace(/(?: *\| *)?\n$/,"").split("\n"):[]}).header.length===a.align.length){for(e=e.substring(i[0].length),p=0;p<a.align.length;p++)/^ *-+: *$/.test(a.align[p])?a.align[p]="right":/^ *:-+: *$/.test(a.align[p])?a.align[p]="center":/^ *:-+ *$/.test(a.align[p])?a.align[p]="left":a.align[p]=null;for(p=0;p<a.cells.length;p++)a.cells[p]=b(a.cells[p].replace(/^ *\| *| *\| *$/g,""),a.header.length);this.tokens.push(a)}else if(i=this.rules.lheading.exec(e))e=e.substring(i[0].length),this.tokens.push({type:"heading",depth:"="===i[2]?1:2,text:i[1]});else if(n&&(i=this.rules.paragraph.exec(e)))e=e.substring(i[0].length),this.tokens.push({type:"paragraph",text:"\n"===i[1].charAt(i[1].length-1)?i[1].slice(0,-1):i[1]});else if(i=this.rules.text.exec(e))e=e.substring(i[0].length),this.tokens.push({type:"text",text:i[0]});else if(e)throw new Error("Infinite loop on byte: "+e.charCodeAt(0));return this.tokens};var r={escape:/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,autolink:/^<(scheme:[^\s\x00-\x1f<>]*|email)>/,url:d,tag:"^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>",link:/^!?\[(label)\]\(href(?:\s+(title))?\s*\)/,reflink:/^!?\[(label)\]\[(?!\s*\])((?:\\[\[\]]?|[^\[\]\\])+)\]/,nolink:/^!?\[(?!\s*\])((?:\[[^\[\]]*\]|\\[\[\]]|[^\[\]])*)\](?:\[\])?/,strong:/^__([^\s][\s\S]*?[^\s])__(?!_)|^\*\*([^\s][\s\S]*?[^\s])\*\*(?!\*)|^__([^\s])__(?!_)|^\*\*([^\s])\*\*(?!\*)/,em:/^_([^\s][\s\S]*?[^\s_])_(?!_)|^_([^\s_][\s\S]*?[^\s])_(?!_)|^\*([^\s][\s\S]*?[^\s*])\*(?!\*)|^\*([^\s*][\s\S]*?[^\s])\*(?!\*)|^_([^\s_])_(?!_)|^\*([^\s*])\*(?!\*)/,code:/^(`+)\s*([\s\S]*?[^`]?)\s*\1(?!`)/,br:/^ {2,}\n(?!\s*$)/,del:d,text:/^[\s\S]+?(?=[\\<!\[`*]|\b_| {2,}\n|$)/};function s(e,t){if(this.options=t||m.defaults,this.links=e,this.rules=r.normal,this.renderer=this.options.renderer||new i,this.renderer.options=this.options,!this.links)throw new Error("Tokens array requires a `links` property.");this.options.pedantic?this.rules=r.pedantic:this.options.gfm&&(this.options.breaks?this.rules=r.breaks:this.rules=r.gfm)}function i(e){this.options=e||m.defaults}function l(){}function o(e){this.tokens=[],this.token=null,this.options=e||m.defaults,this.options.renderer=this.options.renderer||new i,this.renderer=this.options.renderer,this.renderer.options=this.options}function a(e,t){return e.replace(t?/&/g:/&(?!#?\w+;)/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function h(e){return e.replace(/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/gi,function(e,t){return"colon"===(t=t.toLowerCase())?":":"#"===t.charAt(0)?"x"===t.charAt(1)?String.fromCharCode(parseInt(t.substring(2),16)):String.fromCharCode(+t.substring(1)):""})}function p(e,t){return e=e.source||e,t=t||"",{replace:function(t,n){return n=(n=n.source||n).replace(/(^|[^\[])\^/g,"$1"),e=e.replace(t,n),this},getRegex:function(){return new RegExp(e,t)}}}function u(e,t){return c[" "+e]||(/^[^:]+:\/*[^/]*$/.test(e)?c[" "+e]=e+"/":c[" "+e]=e.replace(/[^/]*$/,"")),e=c[" "+e],"//"===t.slice(0,2)?e.replace(/:[\s\S]*/,":")+t:"/"===t.charAt(0)?e.replace(/(:\/*[^/]*)[\s\S]*/,"$1")+t:e+t}r._escapes=/\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g,r._scheme=/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/,r._email=/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/,r.autolink=p(r.autolink).replace("scheme",r._scheme).replace("email",r._email).getRegex(),r._attribute=/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/,r.tag=p(r.tag).replace("comment",t._comment).replace("attribute",r._attribute).getRegex(),r._label=/(?:\[[^\[\]]*\]|\\[\[\]]?|`[^`]*`|[^\[\]\\])*?/,r._href=/\s*(<(?:\\[<>]?|[^\s<>\\])*>|(?:\\[()]?|\([^\s\x00-\x1f()\\]*\)|[^\s\x00-\x1f()\\])*?)/,r._title=/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/,r.link=p(r.link).replace("label",r._label).replace("href",r._href).replace("title",r._title).getRegex(),r.reflink=p(r.reflink).replace("label",r._label).getRegex(),r.normal=f({},r),r.pedantic=f({},r.normal,{strong:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,em:/^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/,link:p(/^!?\[(label)\]\((.*?)\)/).replace("label",r._label).getRegex(),reflink:p(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label",r._label).getRegex()}),r.gfm=f({},r.normal,{escape:p(r.escape).replace("])","~|])").getRegex(),url:p(/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/).replace("email",r._email).getRegex(),_backpedal:/(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/,del:/^~~(?=\S)([\s\S]*?\S)~~/,text:p(r.text).replace("]|","~]|").replace("|","|https?://|ftp://|www\\.|[a-zA-Z0-9.!#$%&'*+/=?^_`{\\|}~-]+@|").getRegex()}),r.breaks=f({},r.gfm,{br:p(r.br).replace("{2,}","*").getRegex(),text:p(r.gfm.text).replace("{2,}","*").getRegex()}),s.rules=r,s.output=function(e,t,n){return new s(t,n).output(e)},s.prototype.output=function(e){for(var t,n,r,i,l,o="";e;)if(l=this.rules.escape.exec(e))e=e.substring(l[0].length),o+=l[1];else if(l=this.rules.autolink.exec(e))e=e.substring(l[0].length),r="@"===l[2]?"mailto:"+(n=a(this.mangle(l[1]))):n=a(l[1]),o+=this.renderer.link(r,null,n);else if(this.inLink||!(l=this.rules.url.exec(e))){if(l=this.rules.tag.exec(e))!this.inLink&&/^<a /i.test(l[0])?this.inLink=!0:this.inLink&&/^<\/a>/i.test(l[0])&&(this.inLink=!1),e=e.substring(l[0].length),o+=this.options.sanitize?this.options.sanitizer?this.options.sanitizer(l[0]):a(l[0]):l[0];else if(l=this.rules.link.exec(e))e=e.substring(l[0].length),this.inLink=!0,r=l[2],this.options.pedantic?(t=/^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(r))?(r=t[1],i=t[3]):i="":i=l[3]?l[3].slice(1,-1):"",r=r.trim().replace(/^<([\s\S]*)>$/,"$1"),o+=this.outputLink(l,{href:s.escapes(r),title:s.escapes(i)}),this.inLink=!1;else if((l=this.rules.reflink.exec(e))||(l=this.rules.nolink.exec(e))){if(e=e.substring(l[0].length),t=(l[2]||l[1]).replace(/\s+/g," "),!(t=this.links[t.toLowerCase()])||!t.href){o+=l[0].charAt(0),e=l[0].substring(1)+e;continue}this.inLink=!0,o+=this.outputLink(l,t),this.inLink=!1}else if(l=this.rules.strong.exec(e))e=e.substring(l[0].length),o+=this.renderer.strong(this.output(l[4]||l[3]||l[2]||l[1]));else if(l=this.rules.em.exec(e))e=e.substring(l[0].length),o+=this.renderer.em(this.output(l[6]||l[5]||l[4]||l[3]||l[2]||l[1]));else if(l=this.rules.code.exec(e))e=e.substring(l[0].length),o+=this.renderer.codespan(a(l[2].trim(),!0));else if(l=this.rules.br.exec(e))e=e.substring(l[0].length),o+=this.renderer.br();else if(l=this.rules.del.exec(e))e=e.substring(l[0].length),o+=this.renderer.del(this.output(l[1]));else if(l=this.rules.text.exec(e))e=e.substring(l[0].length),o+=this.renderer.text(a(this.smartypants(l[0])));else if(e)throw new Error("Infinite loop on byte: "+e.charCodeAt(0))}else l[0]=this.rules._backpedal.exec(l[0])[0],e=e.substring(l[0].length),"@"===l[2]?r="mailto:"+(n=a(l[0])):(n=a(l[0]),r="www."===l[1]?"http://"+n:n),o+=this.renderer.link(r,null,n);return o},s.escapes=function(e){return e?e.replace(s.rules._escapes,"$1"):e},s.prototype.outputLink=function(e,t){var n=t.href,r=t.title?a(t.title):null;return"!"!==e[0].charAt(0)?this.renderer.link(n,r,this.output(e[1])):this.renderer.image(n,r,a(e[1]))},s.prototype.smartypants=function(e){return this.options.smartypants?e.replace(/---/g,"—").replace(/--/g,"–").replace(/(^|[-\u2014/(\[{"\s])'/g,"$1‘").replace(/'/g,"’").replace(/(^|[-\u2014/(\[{\u2018\s])"/g,"$1“").replace(/"/g,"”").replace(/\.{3}/g,"…"):e},s.prototype.mangle=function(e){if(!this.options.mangle)return e;for(var t,n="",r=e.length,s=0;s<r;s++)t=e.charCodeAt(s),Math.random()>.5&&(t="x"+t.toString(16)),n+="&#"+t+";";return n},i.prototype.code=function(e,t,n){if(this.options.highlight){var r=this.options.highlight(e,t);null!=r&&r!==e&&(n=!0,e=r)}return t?'<pre><code class="'+this.options.langPrefix+a(t,!0)+'">'+(n?e:a(e,!0))+"</code></pre>\n":"<pre><code>"+(n?e:a(e,!0))+"</code></pre>"},i.prototype.blockquote=function(e){return"<blockquote>\n"+e+"</blockquote>\n"},i.prototype.html=function(e){return e},i.prototype.heading=function(e,t,n){return this.options.headerIds?"<h"+t+' id="'+this.options.headerPrefix+n.toLowerCase().replace(/[^\w]+/g,"-")+'">'+e+"</h"+t+">\n":"<h"+t+">"+e+"</h"+t+">\n"},i.prototype.hr=function(){return this.options.xhtml?"<hr/>\n":"<hr>\n"},i.prototype.list=function(e,t,n){var r=t?"ol":"ul";return"<"+r+(t&&1!==n?' start="'+n+'"':"")+">\n"+e+"</"+r+">\n"},i.prototype.listitem=function(e){return"<li>"+e+"</li>\n"},i.prototype.checkbox=function(e){return"<input "+(e?'checked="" ':"")+'disabled="" type="checkbox"'+(this.options.xhtml?" /":"")+"> "},i.prototype.paragraph=function(e){return"<p>"+e+"</p>\n"},i.prototype.table=function(e,t){return t&&(t="<tbody>"+t+"</tbody>"),"<table>\n<thead>\n"+e+"</thead>\n"+t+"</table>\n"},i.prototype.tablerow=function(e){return"<tr>\n"+e+"</tr>\n"},i.prototype.tablecell=function(e,t){var n=t.header?"th":"td";return(t.align?"<"+n+' align="'+t.align+'">':"<"+n+">")+e+"</"+n+">\n"},i.prototype.strong=function(e){return"<strong>"+e+"</strong>"},i.prototype.em=function(e){return"<em>"+e+"</em>"},i.prototype.codespan=function(e){return"<code>"+e+"</code>"},i.prototype.br=function(){return this.options.xhtml?"<br/>":"<br>"},i.prototype.del=function(e){return"<del>"+e+"</del>"},i.prototype.link=function(e,t,n){if(this.options.sanitize){try{var r=decodeURIComponent(h(e)).replace(/[^\w:]/g,"").toLowerCase()}catch(e){return n}if(0===r.indexOf("javascript:")||0===r.indexOf("vbscript:")||0===r.indexOf("data:"))return n}this.options.baseUrl&&!g.test(e)&&(e=u(this.options.baseUrl,e));try{e=encodeURI(e).replace(/%25/g,"%")}catch(e){return n}var s='<a href="'+a(e)+'"';return t&&(s+=' title="'+t+'"'),s+=">"+n+"</a>"},i.prototype.image=function(e,t,n){this.options.baseUrl&&!g.test(e)&&(e=u(this.options.baseUrl,e));var r='<img src="'+e+'" alt="'+n+'"';return t&&(r+=' title="'+t+'"'),r+=this.options.xhtml?"/>":">"},i.prototype.text=function(e){return e},l.prototype.strong=l.prototype.em=l.prototype.codespan=l.prototype.del=l.prototype.text=function(e){return e},l.prototype.link=l.prototype.image=function(e,t,n){return""+n},l.prototype.br=function(){return""},o.parse=function(e,t){return new o(t).parse(e)},o.prototype.parse=function(e){this.inline=new s(e.links,this.options),this.inlineText=new s(e.links,f({},this.options,{renderer:new l})),this.tokens=e.reverse();for(var t="";this.next();)t+=this.tok();return t},o.prototype.next=function(){return this.token=this.tokens.pop()},o.prototype.peek=function(){return this.tokens[this.tokens.length-1]||0},o.prototype.parseText=function(){for(var e=this.token.text;"text"===this.peek().type;)e+="\n"+this.next().text;return this.inline.output(e)},o.prototype.tok=function(){switch(this.token.type){case"space":return"";case"hr":return this.renderer.hr();case"heading":return this.renderer.heading(this.inline.output(this.token.text),this.token.depth,h(this.inlineText.output(this.token.text)));case"code":return this.renderer.code(this.token.text,this.token.lang,this.token.escaped);case"table":var e,t,n,r,s="",i="";for(n="",e=0;e<this.token.header.length;e++)n+=this.renderer.tablecell(this.inline.output(this.token.header[e]),{header:!0,align:this.token.align[e]});for(s+=this.renderer.tablerow(n),e=0;e<this.token.cells.length;e++){for(t=this.token.cells[e],n="",r=0;r<t.length;r++)n+=this.renderer.tablecell(this.inline.output(t[r]),{header:!1,align:this.token.align[r]});i+=this.renderer.tablerow(n)}return this.renderer.table(s,i);case"blockquote_start":for(i="";"blockquote_end"!==this.next().type;)i+=this.tok();return this.renderer.blockquote(i);case"list_start":i="";for(var l=this.token.ordered,o=this.token.start;"list_end"!==this.next().type;)i+=this.tok();return this.renderer.list(i,l,o);case"list_item_start":for(i="",this.token.task&&(i+=this.renderer.checkbox(this.token.checked));"list_item_end"!==this.next().type;)i+="text"===this.token.type?this.parseText():this.tok();return this.renderer.listitem(i);case"loose_item_start":for(i="";"list_item_end"!==this.next().type;)i+=this.tok();return this.renderer.listitem(i);case"html":return this.renderer.html(this.token.text);case"paragraph":return this.renderer.paragraph(this.inline.output(this.token.text));case"text":return this.renderer.paragraph(this.parseText())}};var c={},g=/^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;function d(){}function f(e){for(var t,n,r=1;r<arguments.length;r++)for(n in t=arguments[r])Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n]);return e}function b(e,t){var n=e.replace(/([^\\])\|/g,"$1 |").split(/ +\| */),r=0;if(n.length>t)n.splice(t);else for(;n.length<t;)n.push("");for(;r<n.length;r++)n[r]=n[r].replace(/\\\|/g,"|");return n}function m(e,t,r){if(null==e)throw new Error("marked(): input parameter is undefined or null");/*if("string"!=typeof e)throw new Error("marked(): input parameter is of type "+Object.prototype.toString.call(e)+", string expected");*/if(r||"function"==typeof t){r||(r=t,t=null);var s,i,l=(t=f({},m.defaults,t||{})).highlight,h=0;try{s=n.lex(e,t)}catch(e){return r(e)}i=s.length;var p=function(e){if(e)return t.highlight=l,r(e);var n;try{n=o.parse(s,t)}catch(t){e=t}return t.highlight=l,e?r(e):r(null,n)};if(!l||l.length<3)return p();if(delete t.highlight,!i)return p();for(;h<s.length;h++)!function(e){"code"!==e.type?--i||p():l(e.text,e.lang,function(t,n){return t?p(t):null==n||n===e.text?--i||p():(e.text=n,e.escaped=!0,void(--i||p()))})}(s[h])}else try{return t&&(t=f({},m.defaults,t)),o.parse(n.lex(e,t),t)}catch(e){if(e.message+="\nPlease report this to https://github.com/markedjs/marked.",(t||m.defaults).silent)return"<p>An error occurred:</p><pre>"+a(e.message+"",!0)+"</pre>";throw e}}d.exec=d,m.options=m.setOptions=function(e){return f(m.defaults,e),m},m.getDefaults=function(){return{baseUrl:null,breaks:!1,gfm:!0,headerIds:!0,headerPrefix:"",highlight:null,langPrefix:"language-",mangle:!0,pedantic:!1,renderer:new i,sanitize:!1,sanitizer:null,silent:!1,smartLists:!1,smartypants:!1,tables:!0,xhtml:!1}},m.defaults=m.getDefaults(),m.Parser=o,m.parser=o.parse,m.Renderer=i,m.TextRenderer=l,m.Lexer=n,m.lexer=n.lex,m.InlineLexer=s,m.inlineLexer=s.output,m.parse=m,"undefined"!=typeof module&&"object"==typeof exports?module.exports=m:"function"==typeof define&&define.amd?define(function(){return m}):e.marked=m}(this||("undefined"!=typeof window?window:global));
+// b(i[1].replace(/^ *| *\| *$/g,"")) --> i[1].replace(/^ *| *\| *$/g, "").split(/ *\| */)    table没识别的问题
+// header.length===a.align.length --> header.length  table没识别的问题     a.header.length -> a.cells[p].split('|').length - 2 
+!function(e){"use strict";var t={newline:/^\n+/,code:/^( {4}[^\n]+\n*)+/,fences:d,hr:/^ {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\* *){3,})(?:\n+|$)/,heading:/^ *(#{1,6})*([^\n]+?) *(?:#+ *)?(?:\n+|$)/,nptable:d,blockquote:/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,list:/^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,html:"^ {0,3}(?:<(script|pre|style)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?\\?>\\n*|<![A-Z][\\s\\S]*?>\\n*|<!\\[CDATA\\[[\\s\\S]*?\\]\\]>\\n*|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:\\n{2,}|$)|<(?!script|pre|style)([a-z][\\w-]*)(?:attribute)*? */?>(?=\\h*\\n)[\\s\\S]*?(?:\\n{2,}|$)|</(?!script|pre|style)[a-z][\\w-]*\\s*>(?=\\h*\\n)[\\s\\S]*?(?:\\n{2,}|$))",def:/^ {0,3}\[(label)\]: *\n? *<?([^\s>]+)>?(?:(?: +\n? *| *\n *)(title))? *(?:\n+|$)/,table:d,lheading:/^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,paragraph:/^([^\n]+(?:\n(?!hr|heading|lheading| {0,3}>|<\/?(?:tag)(?: +|\n|\/?>)|<(?:script|pre|style|!--))[^\n]+)*)/,text:/^[^\n]+/};function n(e){this.tokens=[],this.tokens.links={},this.options=e||m.defaults,this.rules=t.normal,this.options.pedantic?this.rules=t.pedantic:this.options.gfm&&(this.options.tables?this.rules=t.tables:this.rules=t.gfm)}t._label=/(?!\s*\])(?:\\[\[\]]|[^\[\]])+/,t._title=/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/,t.def=p(t.def).replace("label",t._label).replace("title",t._title).getRegex(),t.bullet=/(?:[*+-]|\d+\.)/,t.item=/^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/,t.item=p(t.item,"gm").replace(/bull/g,t.bullet).getRegex(),t.list=p(t.list).replace(/bull/g,t.bullet).replace("hr","\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))").replace("def","\\n+(?="+t.def.source+")").getRegex(),t._tag="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",t._comment=/<!--(?!-?>)[\s\S]*?-->/,t.html=p(t.html,"i").replace("comment",t._comment).replace("tag",t._tag).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),t.paragraph=p(t.paragraph).replace("hr",t.hr).replace("heading",t.heading).replace("lheading",t.lheading).replace("tag",t._tag).getRegex(),t.blockquote=p(t.blockquote).replace("paragraph",t.paragraph).getRegex(),t.normal=f({},t),t.gfm=f({},t.normal,{fences:/^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\n? *\1 *(?:\n+|$)/,paragraph:/^/,heading:/^ *(#{1,6})+([^\n]+?) *#* *(?:\n+|$)/}),t.gfm.paragraph=p(t.paragraph).replace("(?!","(?!"+t.gfm.fences.source.replace("\\1","\\2")+"|"+t.list.source.replace("\\1","\\3")+"|").getRegex(),t.tables=f({},t.gfm,{nptable:/^ *([^|\n ].*\|.*)\n *([-:]+ *\|[-| :]*)(?:\n((?:.*[^>\n ].*(?:\n|$))*)\n*|$)/,table:/^ *\|(.+)\n *\|?( *[-:]+[-| :]*)(?:\n((?: *[^>\n ].*(?:\n|$))*)\n*|$)/}),t.pedantic=f({},t.normal,{html:p("^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:\"[^\"]*\"|'[^']*'|\\s[^'\"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))").replace("comment",t._comment).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/}),n.rules=t,n.lex=function(e,t){return new n(t).lex(e)},n.prototype.lex=function(e){return e=e.replace(/\r\n|\r/g,"\n").replace(/\t/g,"    ").replace(/\u00a0/g," ").replace(/\u2424/g,"\n"),this.token(e,!0)},n.prototype.token=function(e,n){var r,s,i,l,o,a,h,p,u,c,g,d,f;for(e=e.replace(/^ +$/gm,"");e;)if((i=this.rules.newline.exec(e))&&(e=e.substring(i[0].length),i[0].length>1&&this.tokens.push({type:"space"})),i=this.rules.code.exec(e))e=e.substring(i[0].length),i=i[0].replace(/^ {4}/gm,""),this.tokens.push({type:"code",text:this.options.pedantic?i:i.replace(/\n+$/,"")});else if(i=this.rules.fences.exec(e))e=e.substring(i[0].length),this.tokens.push({type:"code",lang:i[2],text:i[3]||""});else if(i=this.rules.heading.exec(e))e=e.substring(i[0].length),this.tokens.push({type:"heading",depth:i[1].length,text:i[2]});else if(n&&(i=this.rules.nptable.exec(e))&&(a={type:"table",header:i[1].replace(/^ *| *\| *$/g, "").split(/ *\| */),align:i[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:i[3]?i[3].replace(/\n$/,"").split("\n"):[]}).header.length){for(e=e.substring(i[0].length),p=0;p<a.align.length;p++)/^ *-+: *$/.test(a.align[p])?a.align[p]="right":/^ *:-+: *$/.test(a.align[p])?a.align[p]="center":/^ *:-+ *$/.test(a.align[p])?a.align[p]="left":a.align[p]=null;for(p=0;p<a.cells.length;p++)a.cells[p]=b(a.cells[p],a.cells[p].split('|').length - 2 );this.tokens.push(a)}else if(i=this.rules.hr.exec(e))e=e.substring(i[0].length),this.tokens.push({type:"hr"});else if(i=this.rules.blockquote.exec(e))e=e.substring(i[0].length),this.tokens.push({type:"blockquote_start"}),i=i[0].replace(/^ *> ?/gm,""),this.token(i,n),this.tokens.push({type:"blockquote_end"});else if(i=this.rules.list.exec(e)){for(e=e.substring(i[0].length),g=(l=i[2]).length>1,this.tokens.push({type:"list_start",ordered:g,start:g?+l:""}),r=!1,c=(i=i[0].match(this.rules.item)).length,p=0;p<c;p++)h=(a=i[p]).length,~(a=a.replace(/^ *([*+-]|\d+\.) +/,"")).indexOf("\n ")&&(h-=a.length,a=this.options.pedantic?a.replace(/^ {1,4}/gm,""):a.replace(new RegExp("^ {1,"+h+"}","gm"),"")),this.options.smartLists&&p!==c-1&&(l===(o=t.bullet.exec(i[p+1])[0])||l.length>1&&o.length>1||(e=i.slice(p+1).join("\n")+e,p=c-1)),s=r||/\n\n(?!\s*$)/.test(a),p!==c-1&&(r="\n"===a.charAt(a.length-1),s||(s=r)),f=void 0,(d=/^\[[ xX]\] /.test(a))&&(f=" "!==a[1],a=a.replace(/^\[[ xX]\] +/,"")),this.tokens.push({type:s?"loose_item_start":"list_item_start",task:d,checked:f}),this.token(a,!1),this.tokens.push({type:"list_item_end"});this.tokens.push({type:"list_end"})}else if(i=this.rules.html.exec(e))e=e.substring(i[0].length),this.tokens.push({type:this.options.sanitize?"paragraph":"html",pre:!this.options.sanitizer&&("pre"===i[1]||"script"===i[1]||"style"===i[1]),text:i[0]});else if(n&&(i=this.rules.def.exec(e)))e=e.substring(i[0].length),i[3]&&(i[3]=i[3].substring(1,i[3].length-1)),u=i[1].toLowerCase().replace(/\s+/g," "),this.tokens.links[u]||(this.tokens.links[u]={href:i[2],title:i[3]});else if(n&&(i=this.rules.table.exec(e))&&(a={type:"table",header:i[1].replace(/^ *| *\| *$/g, "").split(/ *\| */),align:i[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:i[3]?i[3].replace(/(?: *\| *)?\n$/,"").split("\n"):[]}).header.length){for(e=e.substring(i[0].length),p=0;p<a.align.length;p++)/^ *-+: *$/.test(a.align[p])?a.align[p]="right":/^ *:-+: *$/.test(a.align[p])?a.align[p]="center":/^ *:-+ *$/.test(a.align[p])?a.align[p]="left":a.align[p]=null;for(p=0;p<a.cells.length;p++)a.cells[p]=b(a.cells[p].replace(/^ *\| *| *\| *$/g,""),a.cells[p].split('|').length - 2 );this.tokens.push(a)}else if(i=this.rules.lheading.exec(e))e=e.substring(i[0].length),this.tokens.push({type:"heading",depth:"="===i[2]?1:2,text:i[1]});else if(n&&(i=this.rules.paragraph.exec(e)))e=e.substring(i[0].length),this.tokens.push({type:"paragraph",text:"\n"===i[1].charAt(i[1].length-1)?i[1].slice(0,-1):i[1]});else if(i=this.rules.text.exec(e))e=e.substring(i[0].length),this.tokens.push({type:"text",text:i[0]});else if(e)throw new Error("Infinite loop on byte: "+e.charCodeAt(0));return this.tokens};var r={escape:/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,autolink:/^<(scheme:[^\s\x00-\x1f<>]*|email)>/,url:d,tag:"^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>",link:/^!?\[(label)\]\(href(?:\s+(title))?\s*\)/,reflink:/^!?\[(label)\]\[(?!\s*\])((?:\\[\[\]]?|[^\[\]\\])+)\]/,nolink:/^!?\[(?!\s*\])((?:\[[^\[\]]*\]|\\[\[\]]|[^\[\]])*)\](?:\[\])?/,strong:/^__([^\s][\s\S]*?[^\s])__(?!_)|^\*\*([^\s][\s\S]*?[^\s])\*\*(?!\*)|^__([^\s])__(?!_)|^\*\*([^\s])\*\*(?!\*)/,em:/^_([^\s][\s\S]*?[^\s_])_(?!_)|^_([^\s_][\s\S]*?[^\s])_(?!_)|^\*([^\s][\s\S]*?[^\s*])\*(?!\*)|^\*([^\s*][\s\S]*?[^\s])\*(?!\*)|^_([^\s_])_(?!_)|^\*([^\s*])\*(?!\*)/,code:/^(`+)\s*([\s\S]*?[^`]?)\s*\1(?!`)/,br:/^ {2,}\n(?!\s*$)/,del:d,text:/^[\s\S]+?(?=[\\<!\[`*]|\b_| {2,}\n|$)/};function s(e,t){if(this.options=t||m.defaults,this.links=e,this.rules=r.normal,this.renderer=this.options.renderer||new i,this.renderer.options=this.options,!this.links)throw new Error("Tokens array requires a `links` property.");this.options.pedantic?this.rules=r.pedantic:this.options.gfm&&(this.options.breaks?this.rules=r.breaks:this.rules=r.gfm)}function i(e){this.options=e||m.defaults}function l(){}function o(e){this.tokens=[],this.token=null,this.options=e||m.defaults,this.options.renderer=this.options.renderer||new i,this.renderer=this.options.renderer,this.renderer.options=this.options}function a(e,t){return e.replace(t?/&/g:/&(?!#?\w+;)/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function h(e){return e.replace(/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/gi,function(e,t){return"colon"===(t=t.toLowerCase())?":":"#"===t.charAt(0)?"x"===t.charAt(1)?String.fromCharCode(parseInt(t.substring(2),16)):String.fromCharCode(+t.substring(1)):""})}function p(e,t){return e=e.source||e,t=t||"",{replace:function(t,n){return n=(n=n.source||n).replace(/(^|[^\[])\^/g,"$1"),e=e.replace(t,n),this},getRegex:function(){return new RegExp(e,t)}}}function u(e,t){return c[" "+e]||(/^[^:]+:\/*[^/]*$/.test(e)?c[" "+e]=e+"/":c[" "+e]=e.replace(/[^/]*$/,"")),e=c[" "+e],"//"===t.slice(0,2)?e.replace(/:[\s\S]*/,":")+t:"/"===t.charAt(0)?e.replace(/(:\/*[^/]*)[\s\S]*/,"$1")+t:e+t}r._escapes=/\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g,r._scheme=/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/,r._email=/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/,r.autolink=p(r.autolink).replace("scheme",r._scheme).replace("email",r._email).getRegex(),r._attribute=/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/,r.tag=p(r.tag).replace("comment",t._comment).replace("attribute",r._attribute).getRegex(),r._label=/(?:\[[^\[\]]*\]|\\[\[\]]?|`[^`]*`|[^\[\]\\])*?/,r._href=/\s*(<(?:\\[<>]?|[^\s<>\\])*>|(?:\\[()]?|\([^\s\x00-\x1f()\\]*\)|[^\s\x00-\x1f()\\])*?)/,r._title=/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/,r.link=p(r.link).replace("label",r._label).replace("href",r._href).replace("title",r._title).getRegex(),r.reflink=p(r.reflink).replace("label",r._label).getRegex(),r.normal=f({},r),r.pedantic=f({},r.normal,{strong:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,em:/^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/,link:p(/^!?\[(label)\]\((.*?)\)/).replace("label",r._label).getRegex(),reflink:p(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label",r._label).getRegex()}),r.gfm=f({},r.normal,{escape:p(r.escape).replace("])","~|])").getRegex(),url:p(/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/).replace("email",r._email).getRegex(),_backpedal:/(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/,del:/^~~(?=\S)([\s\S]*?\S)~~/,text:p(r.text).replace("]|","~]|").replace("|","|https?://|ftp://|www\\.|[a-zA-Z0-9.!#$%&'*+/=?^_`{\\|}~-]+@|").getRegex()}),r.breaks=f({},r.gfm,{br:p(r.br).replace("{2,}","*").getRegex(),text:p(r.gfm.text).replace("{2,}","*").getRegex()}),s.rules=r,s.output=function(e,t,n){return new s(t,n).output(e)},s.prototype.output=function(e){for(var t,n,r,i,l,o="";e;)if(l=this.rules.escape.exec(e))e=e.substring(l[0].length),o+=l[1];else if(l=this.rules.autolink.exec(e))e=e.substring(l[0].length),r="@"===l[2]?"mailto:"+(n=a(this.mangle(l[1]))):n=a(l[1]),o+=this.renderer.link(r,null,n);else if(this.inLink||!(l=this.rules.url.exec(e))){if(l=this.rules.tag.exec(e))!this.inLink&&/^<a /i.test(l[0])?this.inLink=!0:this.inLink&&/^<\/a>/i.test(l[0])&&(this.inLink=!1),e=e.substring(l[0].length),o+=this.options.sanitize?this.options.sanitizer?this.options.sanitizer(l[0]):a(l[0]):l[0];else if(l=this.rules.link.exec(e))e=e.substring(l[0].length),this.inLink=!0,r=l[2],this.options.pedantic?(t=/^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(r))?(r=t[1],i=t[3]):i="":i=l[3]?l[3].slice(1,-1):"",r=r.trim().replace(/^<([\s\S]*)>$/,"$1"),o+=this.outputLink(l,{href:s.escapes(r),title:s.escapes(i)}),this.inLink=!1;else if((l=this.rules.reflink.exec(e))||(l=this.rules.nolink.exec(e))){if(e=e.substring(l[0].length),t=(l[2]||l[1]).replace(/\s+/g," "),!(t=this.links[t.toLowerCase()])||!t.href){o+=l[0].charAt(0),e=l[0].substring(1)+e;continue}this.inLink=!0,o+=this.outputLink(l,t),this.inLink=!1}else if(l=this.rules.strong.exec(e))e=e.substring(l[0].length),o+=this.renderer.strong(this.output(l[4]||l[3]||l[2]||l[1]));else if(l=this.rules.em.exec(e))e=e.substring(l[0].length),o+=this.renderer.em(this.output(l[6]||l[5]||l[4]||l[3]||l[2]||l[1]));else if(l=this.rules.code.exec(e))e=e.substring(l[0].length),o+=this.renderer.codespan(a(l[2].trim(),!0));else if(l=this.rules.br.exec(e))e=e.substring(l[0].length),o+=this.renderer.br();else if(l=this.rules.del.exec(e))e=e.substring(l[0].length),o+=this.renderer.del(this.output(l[1]));else if(l=this.rules.text.exec(e))e=e.substring(l[0].length),o+=this.renderer.text(a(this.smartypants(l[0])));else if(e)throw new Error("Infinite loop on byte: "+e.charCodeAt(0))}else l[0]=this.rules._backpedal.exec(l[0])[0],e=e.substring(l[0].length),"@"===l[2]?r="mailto:"+(n=a(l[0])):(n=a(l[0]),r="www."===l[1]?"http://"+n:n),o+=this.renderer.link(r,null,n);return o},s.escapes=function(e){return e?e.replace(s.rules._escapes,"$1"):e},s.prototype.outputLink=function(e,t){var n=t.href,r=t.title?a(t.title):null;return"!"!==e[0].charAt(0)?this.renderer.link(n,r,this.output(e[1])):this.renderer.image(n,r,a(e[1]))},s.prototype.smartypants=function(e){return this.options.smartypants?e.replace(/---/g,"—").replace(/--/g,"–").replace(/(^|[-\u2014/(\[{"\s])'/g,"$1‘").replace(/'/g,"’").replace(/(^|[-\u2014/(\[{\u2018\s])"/g,"$1“").replace(/"/g,"”").replace(/\.{3}/g,"…"):e},s.prototype.mangle=function(e){if(!this.options.mangle)return e;for(var t,n="",r=e.length,s=0;s<r;s++)t=e.charCodeAt(s),Math.random()>.5&&(t="x"+t.toString(16)),n+="&#"+t+";";return n},i.prototype.code=function(e,t,n){if(this.options.highlight){var r=this.options.highlight(e,t);null!=r&&r!==e&&(n=!0,e=r)}return t?'<pre><code class="'+this.options.langPrefix+a(t,!0)+'">'+(n?e:a(e,!0))+"</code></pre>\n":"<pre><code>"+(n?e:a(e,!0))+"</code></pre>"},i.prototype.blockquote=function(e){return"<blockquote>\n"+e+"</blockquote>\n"},i.prototype.html=function(e){return e},i.prototype.heading=function(e,t,n){return this.options.headerIds?"<h"+t+' id="'+this.options.headerPrefix+n.toLowerCase().replace(/[^\w]+/g,"-")+'">'+e+"</h"+t+">\n":"<h"+t+">"+e+"</h"+t+">\n"},i.prototype.hr=function(){return this.options.xhtml?"<hr/>\n":"<hr>\n"},i.prototype.list=function(e,t,n){var r=t?"ol":"ul";return"<"+r+(t&&1!==n?' start="'+n+'"':"")+">\n"+e+"</"+r+">\n"},i.prototype.listitem=function(e){return"<li>"+e+"</li>\n"},i.prototype.checkbox=function(e){return"<input "+(e?'checked="" ':"")+'disabled="" type="checkbox"'+(this.options.xhtml?" /":"")+"> "},i.prototype.paragraph=function(e){return"<p>"+e+"</p>\n"},i.prototype.table=function(e,t){return t&&(t="<tbody>"+t+"</tbody>"),"<table>\n<thead>\n"+e+"</thead>\n"+t+"</table>\n"},i.prototype.tablerow=function(e){return"<tr>\n"+e+"</tr>\n"},i.prototype.tablecell=function(e,t){var n=t.header?"th":"td";return(t.align?"<"+n+' align="'+t.align+'">':"<"+n+">")+e+"</"+n+">\n"},i.prototype.strong=function(e){return"<strong>"+e+"</strong>"},i.prototype.em=function(e){return"<em>"+e+"</em>"},i.prototype.codespan=function(e){return"<code>"+e+"</code>"},i.prototype.br=function(){return this.options.xhtml?"<br/>":"<br>"},i.prototype.del=function(e){return"<del>"+e+"</del>"},i.prototype.link=function(e,t,n){if(this.options.sanitize){try{var r=decodeURIComponent(h(e)).replace(/[^\w:]/g,"").toLowerCase()}catch(e){return n}if(0===r.indexOf("javascript:")||0===r.indexOf("vbscript:")||0===r.indexOf("data:"))return n}this.options.baseUrl&&!g.test(e)&&(e=u(this.options.baseUrl,e));try{e=encodeURI(e).replace(/%25/g,"%")}catch(e){return n}var s='<a href="'+a(e)+'"';return t&&(s+=' title="'+t+'"'),s+=">"+n+"</a>"},i.prototype.image=function(e,t,n){this.options.baseUrl&&!g.test(e)&&(e=u(this.options.baseUrl,e));var r='<img src="'+e+'" alt="'+n+'"';return t&&(r+=' title="'+t+'"'),r+=this.options.xhtml?"/>":">"},i.prototype.text=function(e){return e},l.prototype.strong=l.prototype.em=l.prototype.codespan=l.prototype.del=l.prototype.text=function(e){return e},l.prototype.link=l.prototype.image=function(e,t,n){return""+n},l.prototype.br=function(){return""},o.parse=function(e,t){return new o(t).parse(e)},o.prototype.parse=function(e){this.inline=new s(e.links,this.options),this.inlineText=new s(e.links,f({},this.options,{renderer:new l})),this.tokens=e.reverse();for(var t="";this.next();)t+=this.tok();return t},o.prototype.next=function(){return this.token=this.tokens.pop()},o.prototype.peek=function(){return this.tokens[this.tokens.length-1]||0},o.prototype.parseText=function(){for(var e=this.token.text;"text"===this.peek().type;)e+="\n"+this.next().text;return this.inline.output(e)},o.prototype.tok=function(){switch(this.token.type){case"space":return"";case"hr":return this.renderer.hr();case"heading":return this.renderer.heading(this.inline.output(this.token.text),this.token.depth,h(this.inlineText.output(this.token.text)));case"code":return this.renderer.code(this.token.text,this.token.lang,this.token.escaped);case"table":var e,t,n,r,s="",i="";for(n="",e=0;e<this.token.header.length;e++)n+=this.renderer.tablecell(this.inline.output(this.token.header[e]),{header:!0,align:this.token.align[e]});for(s+=this.renderer.tablerow(n),e=0;e<this.token.cells.length;e++){for(t=this.token.cells[e],n="",r=0;r<t.length;r++)n+=this.renderer.tablecell(this.inline.output(t[r]),{header:!1,align:this.token.align[r]});i+=this.renderer.tablerow(n)}return this.renderer.table(s,i);case"blockquote_start":for(i="";"blockquote_end"!==this.next().type;)i+=this.tok();return this.renderer.blockquote(i);case"list_start":i="";for(var l=this.token.ordered,o=this.token.start;"list_end"!==this.next().type;)i+=this.tok();return this.renderer.list(i,l,o);case"list_item_start":for(i="",this.token.task&&(i+=this.renderer.checkbox(this.token.checked));"list_item_end"!==this.next().type;)i+="text"===this.token.type?this.parseText():this.tok();return this.renderer.listitem(i);case"loose_item_start":for(i="";"list_item_end"!==this.next().type;)i+=this.tok();return this.renderer.listitem(i);case"html":return this.renderer.html(this.token.text);case"paragraph":return this.renderer.paragraph(this.inline.output(this.token.text));case"text":return this.renderer.paragraph(this.parseText())}};var c={},g=/^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;function d(){}function f(e){for(var t,n,r=1;r<arguments.length;r++)for(n in t=arguments[r])Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n]);return e}function b(e,t){var n=e.replace(/([^\\])\|/g,"$1 |").split(/ +\| */),r=0;if(n.length>t)n.splice(t);else for(;n.length<t;)n.push("");for(;r<n.length;r++)n[r]=n[r].replace(/\\\|/g,"|");return n}function m(e,t,r){if(null==e)throw new Error("marked(): input parameter is undefined or null");/*if("string"!=typeof e)throw new Error("marked(): input parameter is of type "+Object.prototype.toString.call(e)+", string expected");*/if(r||"function"==typeof t){r||(r=t,t=null);var s,i,l=(t=f({},m.defaults,t||{})).highlight,h=0;try{s=n.lex(e,t)}catch(e){return r(e)}i=s.length;var p=function(e){if(e)return t.highlight=l,r(e);var n;try{n=o.parse(s,t)}catch(t){e=t}return t.highlight=l,e?r(e):r(null,n)};if(!l||l.length<3)return p();if(delete t.highlight,!i)return p();for(;h<s.length;h++)!function(e){"code"!==e.type?--i||p():l(e.text,e.lang,function(t,n){return t?p(t):null==n||n===e.text?--i||p():(e.text=n,e.escaped=!0,void(--i||p()))})}(s[h])}else try{return t&&(t=f({},m.defaults,t)),o.parse(n.lex(e,t),t)}catch(e){if(e.message+="\nPlease report this to https://github.com/markedjs/marked.",(t||m.defaults).silent)return"<p>An error occurred:</p><pre>"+a(e.message+"",!0)+"</pre>";throw e}}d.exec=d,m.options=m.setOptions=function(e){return f(m.defaults,e),m},m.getDefaults=function(){return{baseUrl:null,breaks:!1,gfm:!0,headerIds:!0,headerPrefix:"",highlight:null,langPrefix:"language-",mangle:!0,pedantic:!1,renderer:new i,sanitize:!1,sanitizer:null,silent:!1,smartLists:!1,smartypants:!1,tables:!0,xhtml:!1}},m.defaults=m.getDefaults(),m.Parser=o,m.parser=o.parse,m.Renderer=i,m.TextRenderer=l,m.Lexer=n,m.lexer=n.lex,m.InlineLexer=s,m.inlineLexer=s.output,m.parse=m,"undefined"!=typeof module&&"object"==typeof exports?module.exports=m:"function"==typeof define&&define.amd?define(function(){return m}):e.marked=m}(this||("undefined"!=typeof window?window:global));
 
diff --git a/public/react/package-lock.json b/public/react/package-lock.json
index 8f387e045..631da270e 100644
--- a/public/react/package-lock.json
+++ b/public/react/package-lock.json
@@ -4,20 +4,6 @@
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
-    "@ant-design/icons": {
-      "version": "1.2.1",
-      "resolved": "http://registry.npm.taobao.org/@ant-design/icons/download/@ant-design/icons-1.2.1.tgz",
-      "integrity": "sha1-jhkwGxQz7GfWu9DoknguKt5WH/k="
-    },
-    "@ant-design/icons-react": {
-      "version": "1.1.5",
-      "resolved": "http://registry.npm.taobao.org/@ant-design/icons-react/download/@ant-design/icons-react-1.1.5.tgz",
-      "integrity": "sha1-GwPajcztKku5gu97JcHSQBTDWmg=",
-      "requires": {
-        "ant-design-palettes": "^1.1.3",
-        "babel-runtime": "^6.26.0"
-      }
-    },
     "@babel/helper-annotate-as-pure": {
       "version": "7.0.0",
       "resolved": "http://registry.npm.taobao.org/@babel/helper-annotate-as-pure/download/@babel/helper-annotate-as-pure-7.0.0.tgz",
@@ -95,15 +81,10 @@
       "resolved": "http://registry.npm.taobao.org/@emotion/unitless/download/@emotion/unitless-0.7.3.tgz",
       "integrity": "sha1-YxCgR/EtIaEDb7AxMXIZiSRAQW8="
     },
-    "@flatten/array": {
-      "version": "1.1.7",
-      "resolved": "https://registry.npm.taobao.org/@flatten/array/download/@flatten/array-1.1.7.tgz",
-      "integrity": "sha1-+UZZu/MtVY9pKmI0MEokcxKm+jg="
-    },
     "@icedesign/base": {
-      "version": "0.2.7",
-      "resolved": "http://registry.npm.taobao.org/@icedesign/base/download/@icedesign/base-0.2.7.tgz",
-      "integrity": "sha1-cFvLHH1UQVQKYuvsJRsGh56oN+U=",
+      "version": "0.2.8",
+      "resolved": "https://registry.npm.taobao.org/@icedesign/base/download/@icedesign/base-0.2.8.tgz",
+      "integrity": "sha1-hmlSY+17gnKJB3sbgoy446sqzAk=",
       "requires": {
         "async-validator": "^1.6.7",
         "classnames": "^2.2.3",
@@ -147,14 +128,6 @@
         "csstype": "^2.2.0"
       }
     },
-    "@types/react-slick": {
-      "version": "0.23.3",
-      "resolved": "http://registry.npm.taobao.org/@types/react-slick/download/@types/react-slick-0.23.3.tgz",
-      "integrity": "sha1-ydFDI6dfVPRqZS+3Rf5VOq0JHOA=",
-      "requires": {
-        "@types/react": "*"
-      }
-    },
     "@types/react-transition-group": {
       "version": "2.9.0",
       "resolved": "http://registry.npm.taobao.org/@types/react-transition-group/download/@types/react-transition-group-2.9.0.tgz?cache=0&other_urls=http%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Freact-transition-group%2Fdownload%2F%40types%2Freact-transition-group-2.9.0.tgz",
@@ -333,102 +306,6 @@
         "color-convert": "^1.9.0"
       }
     },
-    "ant-design-palettes": {
-      "version": "1.1.3",
-      "resolved": "http://registry.npm.taobao.org/ant-design-palettes/download/ant-design-palettes-1.1.3.tgz",
-      "integrity": "sha1-hBGbGk2GNjrcUqONWH5lM2oKJ90=",
-      "requires": {
-        "tinycolor2": "^1.4.1"
-      }
-    },
-    "antd": {
-      "version": "3.16.2",
-      "resolved": "http://registry.npm.taobao.org/antd/download/antd-3.16.2.tgz",
-      "integrity": "sha1-o7SoRKbegubIfJb4jdojF/TYkHU=",
-      "requires": {
-        "@ant-design/icons": "~1.2.0",
-        "@ant-design/icons-react": "~1.1.2",
-        "@types/react-slick": "^0.23.3",
-        "array-tree-filter": "^2.1.0",
-        "babel-runtime": "6.x",
-        "classnames": "~2.2.6",
-        "copy-to-clipboard": "^3.0.8",
-        "create-react-class": "^15.6.3",
-        "create-react-context": "0.2.2",
-        "css-animation": "^1.5.0",
-        "dom-closest": "^0.2.0",
-        "enquire.js": "^2.1.6",
-        "lodash": "^4.17.11",
-        "moment": "^2.24.0",
-        "omit.js": "^1.0.0",
-        "prop-types": "^15.6.2",
-        "raf": "^3.4.0",
-        "rc-animate": "^2.5.4",
-        "rc-calendar": "~9.12.1",
-        "rc-cascader": "~0.17.0",
-        "rc-checkbox": "~2.1.5",
-        "rc-collapse": "~1.11.1",
-        "rc-dialog": "~7.3.0",
-        "rc-drawer": "~1.7.6",
-        "rc-dropdown": "~2.4.1",
-        "rc-editor-mention": "^1.1.7",
-        "rc-form": "^2.4.0",
-        "rc-input-number": "~4.4.0",
-        "rc-menu": "~7.4.12",
-        "rc-notification": "~3.3.0",
-        "rc-pagination": "~1.17.7",
-        "rc-progress": "~2.3.0",
-        "rc-rate": "~2.5.0",
-        "rc-select": "~9.0.0",
-        "rc-slider": "~8.6.5",
-        "rc-steps": "~3.3.0",
-        "rc-switch": "~1.9.0",
-        "rc-table": "~6.4.0",
-        "rc-tabs": "~9.6.0",
-        "rc-time-picker": "~3.6.1",
-        "rc-tooltip": "~3.7.3",
-        "rc-tree": "~1.15.2",
-        "rc-tree-select": "~2.6.0",
-        "rc-trigger": "^2.6.2",
-        "rc-upload": "~2.6.0",
-        "rc-util": "^4.5.1",
-        "react-lazy-load": "^3.0.13",
-        "react-lifecycles-compat": "^3.0.4",
-        "react-slick": "~0.23.2",
-        "resize-observer-polyfill": "^1.5.0",
-        "shallowequal": "^1.1.0",
-        "warning": "~4.0.2"
-      },
-      "dependencies": {
-        "rc-select": {
-          "version": "9.0.2",
-          "resolved": "http://registry.npm.taobao.org/rc-select/download/rc-select-9.0.2.tgz",
-          "integrity": "sha1-zg0pfbX4pcfou8P8JNntW6ZIASw=",
-          "requires": {
-            "babel-runtime": "^6.23.0",
-            "classnames": "2.x",
-            "component-classes": "1.x",
-            "dom-scroll-into-view": "1.x",
-            "prop-types": "^15.5.8",
-            "raf": "^3.4.0",
-            "rc-animate": "2.x",
-            "rc-menu": "^7.3.0",
-            "rc-trigger": "^2.5.4",
-            "rc-util": "^4.0.4",
-            "react-lifecycles-compat": "^3.0.2",
-            "warning": "^4.0.2"
-          }
-        },
-        "warning": {
-          "version": "4.0.3",
-          "resolved": "http://registry.npm.taobao.org/warning/download/warning-4.0.3.tgz",
-          "integrity": "sha1-Fungd+uKhtavfWSqHgX9hbRnjKM=",
-          "requires": {
-            "loose-envify": "^1.0.0"
-          }
-        }
-      }
-    },
     "anymatch": {
       "version": "1.3.2",
       "resolved": "http://registry.npm.taobao.org/anymatch/download/anymatch-1.3.2.tgz",
@@ -520,11 +397,6 @@
       "resolved": "http://registry.npm.taobao.org/array-reduce/download/array-reduce-0.0.0.tgz",
       "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys="
     },
-    "array-tree-filter": {
-      "version": "2.1.0",
-      "resolved": "http://registry.npm.taobao.org/array-tree-filter/download/array-tree-filter-2.1.0.tgz",
-      "integrity": "sha1-hzrAD+yDdJ8lWsjdCDgUtPYykZA="
-    },
     "array-union": {
       "version": "1.0.2",
       "resolved": "http://registry.npm.taobao.org/array-union/download/array-union-1.0.2.tgz",
@@ -629,12 +501,9 @@
       "dev": true
     },
     "async-validator": {
-      "version": "1.11.0",
-      "resolved": "http://registry.npm.taobao.org/async-validator/download/async-validator-1.11.0.tgz",
-      "integrity": "sha1-9i/RS8yjNvzalubdU9vR3dP8MZg=",
-      "requires": {
-        "babel-runtime": "6.x"
-      }
+      "version": "1.12.2",
+      "resolved": "https://registry.npm.taobao.org/async-validator/download/async-validator-1.12.2.tgz",
+      "integrity": "sha1-vq5nHnF00pOLe0tp0vt+cit/1yw="
     },
     "asynckit": {
       "version": "0.4.0",
@@ -2825,14 +2694,6 @@
       "resolved": "http://registry.npm.taobao.org/copy-descriptor/download/copy-descriptor-0.1.1.tgz",
       "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40="
     },
-    "copy-to-clipboard": {
-      "version": "3.1.0",
-      "resolved": "http://registry.npm.taobao.org/copy-to-clipboard/download/copy-to-clipboard-3.1.0.tgz",
-      "integrity": "sha1-CigUGJnmvSF7ncE/0WibOziCC0Q=",
-      "requires": {
-        "toggle-selection": "^1.0.6"
-      }
-    },
     "core-js": {
       "version": "2.6.5",
       "resolved": "http://registry.npm.taobao.org/core-js/download/core-js-2.6.5.tgz",
@@ -2916,18 +2777,9 @@
         "object-assign": "^4.1.1"
       }
     },
-    "create-react-context": {
-      "version": "0.2.2",
-      "resolved": "http://registry.npm.taobao.org/create-react-context/download/create-react-context-0.2.2.tgz",
-      "integrity": "sha1-mDZUL5qqIoaM19Sm+CZn3zgBnco=",
-      "requires": {
-        "fbjs": "^0.8.0",
-        "gud": "^1.0.0"
-      }
-    },
     "cropperjs": {
       "version": "0.7.2",
-      "resolved": "http://registry.npm.taobao.org/cropperjs/download/cropperjs-0.7.2.tgz",
+      "resolved": "https://registry.npm.taobao.org/cropperjs/download/cropperjs-0.7.2.tgz",
       "integrity": "sha1-atinHbAGKbqULZzt5lKyeXXp50o="
     },
     "cross-spawn": {
@@ -3494,14 +3346,6 @@
       "resolved": "http://registry.npm.taobao.org/dom-align/download/dom-align-1.8.2.tgz",
       "integrity": "sha1-/c02vOJbqNNP41gu/Vesdn30kL0="
     },
-    "dom-closest": {
-      "version": "0.2.0",
-      "resolved": "http://registry.npm.taobao.org/dom-closest/download/dom-closest-0.2.0.tgz",
-      "integrity": "sha1-69n5HRvyLo1vR3h2u80+yQIWwM8=",
-      "requires": {
-        "dom-matches": ">=1.0.1"
-      }
-    },
     "dom-converter": {
       "version": "0.2.0",
       "resolved": "http://registry.npm.taobao.org/dom-converter/download/dom-converter-0.2.0.tgz",
@@ -3533,11 +3377,6 @@
         }
       }
     },
-    "dom-matches": {
-      "version": "2.0.0",
-      "resolved": "http://registry.npm.taobao.org/dom-matches/download/dom-matches-2.0.0.tgz",
-      "integrity": "sha1-0nKLQWqHUzmA6wibhI0lPPI6dYw="
-    },
     "dom-scroll-into-view": {
       "version": "1.2.1",
       "resolved": "http://registry.npm.taobao.org/dom-scroll-into-view/download/dom-scroll-into-view-1.2.1.tgz",
@@ -3610,23 +3449,6 @@
       "resolved": "http://registry.npm.taobao.org/dotenv-expand/download/dotenv-expand-4.2.0.tgz",
       "integrity": "sha1-3vHxyl1gWdJKdm5YeULCEQbOEnU="
     },
-    "draft-js": {
-      "version": "0.10.5",
-      "resolved": "http://registry.npm.taobao.org/draft-js/download/draft-js-0.10.5.tgz",
-      "integrity": "sha1-v6m+sBj+BTPbsI1mdcNxprCPp0I=",
-      "requires": {
-        "fbjs": "^0.8.15",
-        "immutable": "~3.7.4",
-        "object-assign": "^4.1.0"
-      },
-      "dependencies": {
-        "immutable": {
-          "version": "3.7.6",
-          "resolved": "http://registry.npm.taobao.org/immutable/download/immutable-3.7.6.tgz",
-          "integrity": "sha1-E7TTyxK++hVIKib+Gy665kAHHks="
-        }
-      }
-    },
     "duplexer": {
       "version": "0.1.1",
       "resolved": "http://registry.npm.taobao.org/duplexer/download/duplexer-0.1.1.tgz",
@@ -4220,11 +4042,6 @@
       "resolved": "http://registry.npm.taobao.org/eventemitter3/download/eventemitter3-3.1.0.tgz",
       "integrity": "sha1-CQtNbNvWRe0Qv3UNS1QHlC17oWM="
     },
-    "eventlistener": {
-      "version": "0.0.1",
-      "resolved": "http://registry.npm.taobao.org/eventlistener/download/eventlistener-0.0.1.tgz",
-      "integrity": "sha1-7Suqu4UiJ68rz4iRUscsY8pTLrg="
-    },
     "events": {
       "version": "3.0.0",
       "resolved": "http://registry.npm.taobao.org/events/download/events-3.0.0.tgz",
@@ -5306,11 +5123,6 @@
       "resolved": "http://registry.npm.taobao.org/growly/download/growly-1.3.0.tgz",
       "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE="
     },
-    "gud": {
-      "version": "1.0.0",
-      "resolved": "http://registry.npm.taobao.org/gud/download/gud-1.0.0.tgz",
-      "integrity": "sha1-pIlYGxfmpwvsqavjrlfeekmYUsA="
-    },
     "gzip-size": {
       "version": "3.0.0",
       "resolved": "http://registry.npm.taobao.org/gzip-size/download/gzip-size-3.0.0.tgz",
@@ -5319,11 +5131,6 @@
         "duplexer": "^0.1.1"
       }
     },
-    "hammerjs": {
-      "version": "2.0.8",
-      "resolved": "http://registry.npm.taobao.org/hammerjs/download/hammerjs-2.0.8.tgz",
-      "integrity": "sha1-BO93hiz/K7edMPdpIJWTAiK/YPE="
-    },
     "handle-thing": {
       "version": "1.2.5",
       "resolved": "http://registry.npm.taobao.org/handle-thing/download/handle-thing-1.2.5.tgz",
@@ -6713,14 +6520,6 @@
       "resolved": "http://registry.npm.taobao.org/json-stringify-safe/download/json-stringify-safe-5.0.1.tgz",
       "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
     },
-    "json2mq": {
-      "version": "0.2.0",
-      "resolved": "http://registry.npm.taobao.org/json2mq/download/json2mq-0.2.0.tgz",
-      "integrity": "sha1-tje9O6nqvhIsg+lyBIOusQ0skEo=",
-      "requires": {
-        "string-convert": "^0.2.0"
-      }
-    },
     "json3": {
       "version": "3.3.2",
       "resolved": "http://registry.npm.taobao.org/json3/download/json3-3.3.2.tgz",
@@ -7100,11 +6899,6 @@
         "lodash._reinterpolate": "~3.0.0"
       }
     },
-    "lodash.throttle": {
-      "version": "4.1.1",
-      "resolved": "http://registry.npm.taobao.org/lodash.throttle/download/lodash.throttle-4.1.1.tgz",
-      "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ="
-    },
     "lodash.uniq": {
       "version": "4.5.0",
       "resolved": "http://registry.npm.taobao.org/lodash.uniq/download/lodash.uniq-4.5.0.tgz",
@@ -7808,14 +7602,6 @@
       "resolved": "http://registry.npm.taobao.org/obuf/download/obuf-1.1.2.tgz",
       "integrity": "sha1-Cb6jND1BhZ69RGKS0RydTbYZCE4="
     },
-    "omit.js": {
-      "version": "1.0.2",
-      "resolved": "http://registry.npm.taobao.org/omit.js/download/omit.js-1.0.2.tgz",
-      "integrity": "sha1-kaFPDrqEBm36AVvzDkdMR/MLyFg=",
-      "requires": {
-        "babel-runtime": "^6.23.0"
-      }
-    },
     "on-finished": {
       "version": "2.3.0",
       "resolved": "http://registry.npm.taobao.org/on-finished/download/on-finished-2.3.0.tgz",
@@ -9333,11 +9119,6 @@
       "resolved": "http://registry.npm.taobao.org/preserve/download/preserve-0.2.0.tgz",
       "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks="
     },
-    "prettier": {
-      "version": "1.17.0",
-      "resolved": "http://registry.npm.taobao.org/prettier/download/prettier-1.17.0.tgz",
-      "integrity": "sha1-U7MDZ27tIswUqfDOwJtHezAmwAg="
-    },
     "pretty-bytes": {
       "version": "4.0.2",
       "resolved": "http://registry.npm.taobao.org/pretty-bytes/download/pretty-bytes-4.0.2.tgz",
@@ -9603,130 +9384,6 @@
         "react-lifecycles-compat": "^3.0.4"
       }
     },
-    "rc-calendar": {
-      "version": "9.12.4",
-      "resolved": "http://registry.npm.taobao.org/rc-calendar/download/rc-calendar-9.12.4.tgz",
-      "integrity": "sha1-aO46hXtTQdeA2Uc1QZJs/gtEkVQ=",
-      "requires": {
-        "babel-runtime": "6.x",
-        "classnames": "2.x",
-        "moment": "2.x",
-        "prop-types": "^15.5.8",
-        "rc-trigger": "^2.2.0",
-        "rc-util": "^4.1.1",
-        "react-lifecycles-compat": "^3.0.4"
-      }
-    },
-    "rc-cascader": {
-      "version": "0.17.1",
-      "resolved": "http://registry.npm.taobao.org/rc-cascader/download/rc-cascader-0.17.1.tgz",
-      "integrity": "sha1-kUSBwzcLX9j4Lk+d+bZZbf7aFNU=",
-      "requires": {
-        "array-tree-filter": "^2.1.0",
-        "prop-types": "^15.5.8",
-        "rc-trigger": "^2.2.0",
-        "rc-util": "^4.0.4",
-        "react-lifecycles-compat": "^3.0.4",
-        "shallow-equal": "^1.0.0",
-        "warning": "^4.0.1"
-      },
-      "dependencies": {
-        "warning": {
-          "version": "4.0.3",
-          "resolved": "http://registry.npm.taobao.org/warning/download/warning-4.0.3.tgz",
-          "integrity": "sha1-Fungd+uKhtavfWSqHgX9hbRnjKM=",
-          "requires": {
-            "loose-envify": "^1.0.0"
-          }
-        }
-      }
-    },
-    "rc-checkbox": {
-      "version": "2.1.6",
-      "resolved": "http://registry.npm.taobao.org/rc-checkbox/download/rc-checkbox-2.1.6.tgz",
-      "integrity": "sha1-XcAGU+UncBjEMf7FXji5HB+XbpA=",
-      "requires": {
-        "babel-runtime": "^6.23.0",
-        "classnames": "2.x",
-        "prop-types": "15.x",
-        "rc-util": "^4.0.4"
-      }
-    },
-    "rc-collapse": {
-      "version": "1.11.1",
-      "resolved": "http://registry.npm.taobao.org/rc-collapse/download/rc-collapse-1.11.1.tgz",
-      "integrity": "sha1-SqCXetv1Ip19tYIFZGsTkFrdcq0=",
-      "requires": {
-        "classnames": "2.x",
-        "css-animation": "1.x",
-        "prop-types": "^15.5.6",
-        "rc-animate": "2.x",
-        "react-is": "^16.7.0",
-        "shallowequal": "^1.1.0"
-      }
-    },
-    "rc-dialog": {
-      "version": "7.3.1",
-      "resolved": "http://registry.npm.taobao.org/rc-dialog/download/rc-dialog-7.3.1.tgz",
-      "integrity": "sha1-RQQew1v8jjN8kbZLUs6+9upc1KI=",
-      "requires": {
-        "babel-runtime": "6.x",
-        "rc-animate": "2.x",
-        "rc-util": "^4.4.0"
-      }
-    },
-    "rc-drawer": {
-      "version": "1.7.7",
-      "resolved": "http://registry.npm.taobao.org/rc-drawer/download/rc-drawer-1.7.7.tgz",
-      "integrity": "sha1-sBTR3lJFfIXE8+Hw1kelQDHdJgw=",
-      "requires": {
-        "babel-runtime": "6.x",
-        "classnames": "^2.2.5",
-        "prop-types": "^15.5.0",
-        "rc-util": "^4.5.1"
-      }
-    },
-    "rc-dropdown": {
-      "version": "2.4.1",
-      "resolved": "http://registry.npm.taobao.org/rc-dropdown/download/rc-dropdown-2.4.1.tgz",
-      "integrity": "sha1-qu9us6UVLN2ZgolcKnjZtfBGzew=",
-      "requires": {
-        "babel-runtime": "^6.26.0",
-        "classnames": "^2.2.6",
-        "prop-types": "^15.5.8",
-        "rc-trigger": "^2.5.1",
-        "react-lifecycles-compat": "^3.0.2"
-      }
-    },
-    "rc-editor-core": {
-      "version": "0.8.9",
-      "resolved": "http://registry.npm.taobao.org/rc-editor-core/download/rc-editor-core-0.8.9.tgz",
-      "integrity": "sha1-9hGVLI7tll4+NI2ErnvohdrrIhw=",
-      "requires": {
-        "babel-runtime": "^6.26.0",
-        "classnames": "^2.2.5",
-        "draft-js": "^0.10.0",
-        "immutable": "^3.7.4",
-        "lodash": "^4.16.5",
-        "prop-types": "^15.5.8",
-        "setimmediate": "^1.0.5"
-      }
-    },
-    "rc-editor-mention": {
-      "version": "1.1.12",
-      "resolved": "http://registry.npm.taobao.org/rc-editor-mention/download/rc-editor-mention-1.1.12.tgz",
-      "integrity": "sha1-iWvLFyES8YgS6W/dM7pgPA/HMGo=",
-      "requires": {
-        "babel-runtime": "^6.23.0",
-        "classnames": "^2.2.5",
-        "dom-scroll-into-view": "^1.2.0",
-        "draft-js": "~0.10.0",
-        "immutable": "^3.7.4",
-        "prop-types": "^15.5.8",
-        "rc-animate": "^2.3.0",
-        "rc-editor-core": "~0.8.3"
-      }
-    },
     "rc-form": {
       "version": "2.4.4",
       "resolved": "http://registry.npm.taobao.org/rc-form/download/rc-form-2.4.4.tgz",
@@ -9759,28 +9416,6 @@
         }
       }
     },
-    "rc-hammerjs": {
-      "version": "0.6.9",
-      "resolved": "http://registry.npm.taobao.org/rc-hammerjs/download/rc-hammerjs-0.6.9.tgz",
-      "integrity": "sha1-mk3b2hsuyPm5WWCRpqmJhCokOQc=",
-      "requires": {
-        "babel-runtime": "6.x",
-        "hammerjs": "^2.0.8",
-        "prop-types": "^15.5.9"
-      }
-    },
-    "rc-input-number": {
-      "version": "4.4.1",
-      "resolved": "http://registry.npm.taobao.org/rc-input-number/download/rc-input-number-4.4.1.tgz",
-      "integrity": "sha1-FjbPKBzejXjqTIuf/P/Xe4A1BnU=",
-      "requires": {
-        "babel-runtime": "6.x",
-        "classnames": "^2.2.0",
-        "prop-types": "^15.5.7",
-        "rc-util": "^4.5.1",
-        "rmc-feedback": "^2.0.0"
-      }
-    },
     "rc-menu": {
       "version": "7.4.22",
       "resolved": "http://registry.npm.taobao.org/rc-menu/download/rc-menu-7.4.22.tgz",
@@ -9799,18 +9434,6 @@
         "resize-observer-polyfill": "^1.5.0"
       }
     },
-    "rc-notification": {
-      "version": "3.3.1",
-      "resolved": "http://registry.npm.taobao.org/rc-notification/download/rc-notification-3.3.1.tgz",
-      "integrity": "sha1-C6o+cPjUCrAVzo+njCYMSQ/HvrQ=",
-      "requires": {
-        "babel-runtime": "6.x",
-        "classnames": "2.x",
-        "prop-types": "^15.5.8",
-        "rc-animate": "2.x",
-        "rc-util": "^4.0.4"
-      }
-    },
     "rc-pagination": {
       "version": "1.17.14",
       "resolved": "http://registry.npm.taobao.org/rc-pagination/download/rc-pagination-1.17.14.tgz",
@@ -9821,15 +9444,6 @@
         "react-lifecycles-compat": "^3.0.4"
       }
     },
-    "rc-progress": {
-      "version": "2.3.0",
-      "resolved": "http://registry.npm.taobao.org/rc-progress/download/rc-progress-2.3.0.tgz",
-      "integrity": "sha1-z70H/5AmxFAQCYDeIJqSZQ4k8xM=",
-      "requires": {
-        "babel-runtime": "6.x",
-        "prop-types": "^15.5.8"
-      }
-    },
     "rc-rate": {
       "version": "2.5.0",
       "resolved": "http://registry.npm.taobao.org/rc-rate/download/rc-rate-2.5.0.tgz",
@@ -9870,116 +9484,6 @@
         }
       }
     },
-    "rc-slider": {
-      "version": "8.6.9",
-      "resolved": "http://registry.npm.taobao.org/rc-slider/download/rc-slider-8.6.9.tgz",
-      "integrity": "sha1-syFIpJjJJ8k/INwflehoLEkkv44=",
-      "requires": {
-        "babel-runtime": "6.x",
-        "classnames": "^2.2.5",
-        "prop-types": "^15.5.4",
-        "rc-tooltip": "^3.7.0",
-        "rc-util": "^4.0.4",
-        "shallowequal": "^1.0.1",
-        "warning": "^4.0.3"
-      },
-      "dependencies": {
-        "warning": {
-          "version": "4.0.3",
-          "resolved": "http://registry.npm.taobao.org/warning/download/warning-4.0.3.tgz",
-          "integrity": "sha1-Fungd+uKhtavfWSqHgX9hbRnjKM=",
-          "requires": {
-            "loose-envify": "^1.0.0"
-          }
-        }
-      }
-    },
-    "rc-steps": {
-      "version": "3.3.1",
-      "resolved": "http://registry.npm.taobao.org/rc-steps/download/rc-steps-3.3.1.tgz",
-      "integrity": "sha1-SHfiiXMx47/ba3ieiK6nj08V9zI=",
-      "requires": {
-        "babel-runtime": "^6.23.0",
-        "classnames": "^2.2.3",
-        "lodash": "^4.17.5",
-        "prop-types": "^15.5.7"
-      }
-    },
-    "rc-switch": {
-      "version": "1.9.0",
-      "resolved": "http://registry.npm.taobao.org/rc-switch/download/rc-switch-1.9.0.tgz",
-      "integrity": "sha1-qyuHjycTxoE1ikUzkZdsm5WykPc=",
-      "requires": {
-        "classnames": "^2.2.1",
-        "prop-types": "^15.5.6",
-        "react-lifecycles-compat": "^3.0.4"
-      }
-    },
-    "rc-table": {
-      "version": "6.4.4",
-      "resolved": "http://registry.npm.taobao.org/rc-table/download/rc-table-6.4.4.tgz",
-      "integrity": "sha1-fOS4VuooFIRKAWQeyKzy1y7jpao=",
-      "requires": {
-        "babel-runtime": "6.x",
-        "classnames": "^2.2.5",
-        "component-classes": "^1.2.6",
-        "lodash": "^4.17.5",
-        "mini-store": "^2.0.0",
-        "prop-types": "^15.5.8",
-        "rc-util": "^4.0.4",
-        "react-lifecycles-compat": "^3.0.2",
-        "shallowequal": "^1.0.2",
-        "warning": "^3.0.0"
-      }
-    },
-    "rc-tabs": {
-      "version": "9.6.3",
-      "resolved": "http://registry.npm.taobao.org/rc-tabs/download/rc-tabs-9.6.3.tgz",
-      "integrity": "sha1-XuAoFlIXafkuKNwDYKLrEhS1MHU=",
-      "requires": {
-        "babel-runtime": "6.x",
-        "classnames": "2.x",
-        "create-react-context": "0.2.2",
-        "lodash": "^4.17.5",
-        "prop-types": "15.x",
-        "raf": "^3.4.1",
-        "rc-hammerjs": "~0.6.0",
-        "rc-util": "^4.0.4",
-        "resize-observer-polyfill": "^1.5.1",
-        "warning": "^3.0.0"
-      },
-      "dependencies": {
-        "raf": {
-          "version": "3.4.1",
-          "resolved": "http://registry.npm.taobao.org/raf/download/raf-3.4.1.tgz",
-          "integrity": "sha1-B0LpmkplUvRF1z4+4DKK8P8e3jk=",
-          "requires": {
-            "performance-now": "^2.1.0"
-          }
-        }
-      }
-    },
-    "rc-time-picker": {
-      "version": "3.6.3",
-      "resolved": "http://registry.npm.taobao.org/rc-time-picker/download/rc-time-picker-3.6.3.tgz",
-      "integrity": "sha1-kV2R1oAWcknTJIcZ4IoxzqpcOwE=",
-      "requires": {
-        "classnames": "2.x",
-        "moment": "2.x",
-        "prop-types": "^15.5.8",
-        "rc-trigger": "^2.2.0"
-      }
-    },
-    "rc-tooltip": {
-      "version": "3.7.3",
-      "resolved": "http://registry.npm.taobao.org/rc-tooltip/download/rc-tooltip-3.7.3.tgz",
-      "integrity": "sha1-KArsavyqROjf8EgPuv+eh/wArsw=",
-      "requires": {
-        "babel-runtime": "6.x",
-        "prop-types": "^15.5.8",
-        "rc-trigger": "^2.2.2"
-      }
-    },
     "rc-tree": {
       "version": "1.15.2",
       "resolved": "http://registry.npm.taobao.org/rc-tree/download/rc-tree-1.15.2.tgz",
@@ -10011,63 +9515,6 @@
         }
       }
     },
-    "rc-tree-select": {
-      "version": "2.6.2",
-      "resolved": "http://registry.npm.taobao.org/rc-tree-select/download/rc-tree-select-2.6.2.tgz",
-      "integrity": "sha1-eDuvvzq9D8ZFoHaXVjA47aYwLyk=",
-      "requires": {
-        "classnames": "^2.2.1",
-        "dom-scroll-into-view": "^1.2.1",
-        "prop-types": "^15.5.8",
-        "raf": "^3.4.0",
-        "rc-animate": "^3.0.0-rc.4",
-        "rc-tree": "~1.15.0",
-        "rc-trigger": "^3.0.0-rc.2",
-        "rc-util": "^4.5.0",
-        "react-lifecycles-compat": "^3.0.4",
-        "shallowequal": "^1.0.2",
-        "warning": "^4.0.1"
-      },
-      "dependencies": {
-        "rc-animate": {
-          "version": "3.0.0-rc.6",
-          "resolved": "http://registry.npm.taobao.org/rc-animate/download/rc-animate-3.0.0-rc.6.tgz",
-          "integrity": "sha1-BCiO76EY4MriFFNsipA/+qwbw/s=",
-          "requires": {
-            "babel-runtime": "6.x",
-            "classnames": "^2.2.5",
-            "component-classes": "^1.2.6",
-            "fbjs": "^0.8.16",
-            "prop-types": "15.x",
-            "raf": "^3.4.0",
-            "rc-util": "^4.5.0",
-            "react-lifecycles-compat": "^3.0.4"
-          }
-        },
-        "rc-trigger": {
-          "version": "3.0.0-rc.3",
-          "resolved": "http://registry.npm.taobao.org/rc-trigger/download/rc-trigger-3.0.0-rc.3.tgz",
-          "integrity": "sha1-NYQt8WdNJTFeFCakSIKkyXZSJYs=",
-          "requires": {
-            "babel-runtime": "6.x",
-            "classnames": "^2.2.6",
-            "prop-types": "15.x",
-            "raf": "^3.4.0",
-            "rc-align": "^2.4.1",
-            "rc-animate": "^3.0.0-rc.1",
-            "rc-util": "^4.4.0"
-          }
-        },
-        "warning": {
-          "version": "4.0.3",
-          "resolved": "http://registry.npm.taobao.org/warning/download/warning-4.0.3.tgz",
-          "integrity": "sha1-Fungd+uKhtavfWSqHgX9hbRnjKM=",
-          "requires": {
-            "loose-envify": "^1.0.0"
-          }
-        }
-      }
-    },
     "rc-trigger": {
       "version": "2.6.2",
       "resolved": "http://registry.npm.taobao.org/rc-trigger/download/rc-trigger-2.6.2.tgz",
@@ -10181,17 +9628,6 @@
         "text-table": "0.2.0"
       }
     },
-    "react-dom": {
-      "version": "16.8.6",
-      "resolved": "http://registry.npm.taobao.org/react-dom/download/react-dom-16.8.6.tgz",
-      "integrity": "sha1-cdYwP2MeiwCX9WFl72CPBR/24Q8=",
-      "requires": {
-        "loose-envify": "^1.1.0",
-        "object-assign": "^4.1.1",
-        "prop-types": "^15.6.2",
-        "scheduler": "^0.13.6"
-      }
-    },
     "react-error-overlay": {
       "version": "4.0.1",
       "resolved": "http://registry.npm.taobao.org/react-error-overlay/download/react-error-overlay-4.0.1.tgz",
@@ -10274,17 +9710,6 @@
         }
       }
     },
-    "react-lazy-load": {
-      "version": "3.0.13",
-      "resolved": "http://registry.npm.taobao.org/react-lazy-load/download/react-lazy-load-3.0.13.tgz",
-      "integrity": "sha1-OwqS0zbUPT8Nc8vm81sXBQsIuCQ=",
-      "requires": {
-        "eventlistener": "0.0.1",
-        "lodash.debounce": "^4.0.0",
-        "lodash.throttle": "^4.0.0",
-        "prop-types": "^15.5.8"
-      }
-    },
     "react-lifecycles-compat": {
       "version": "3.0.4",
       "resolved": "http://registry.npm.taobao.org/react-lifecycles-compat/download/react-lifecycles-compat-3.0.4.tgz",
@@ -10390,22 +9815,9 @@
         "stifle": "^1.0.2"
       }
     },
-    "react-slick": {
-      "version": "0.23.2",
-      "resolved": "http://registry.npm.taobao.org/react-slick/download/react-slick-0.23.2.tgz",
-      "integrity": "sha1-jYvbx3pmeOitNvUMMleMfA8cVPY=",
-      "requires": {
-        "classnames": "^2.2.5",
-        "enquire.js": "^2.1.6",
-        "json2mq": "^0.2.0",
-        "lodash.debounce": "^4.0.8",
-        "prettier": "^1.14.3",
-        "resize-observer-polyfill": "^1.5.0"
-      }
-    },
     "react-transition-group": {
       "version": "1.2.1",
-      "resolved": "http://registry.npm.taobao.org/react-transition-group/download/react-transition-group-1.2.1.tgz",
+      "resolved": "https://registry.npm.taobao.org/react-transition-group/download/react-transition-group-1.2.1.tgz",
       "integrity": "sha1-4R9yslf5IbITIpp3TfRmEjRsfKY=",
       "requires": {
         "chain-function": "^1.0.0",
@@ -11135,15 +10547,6 @@
         "inherits": "^2.0.1"
       }
     },
-    "rmc-feedback": {
-      "version": "2.0.0",
-      "resolved": "http://registry.npm.taobao.org/rmc-feedback/download/rmc-feedback-2.0.0.tgz",
-      "integrity": "sha1-y8bLOuY8emNe7w4l5PuvWsNm7qo=",
-      "requires": {
-        "babel-runtime": "6.x",
-        "classnames": "^2.2.5"
-      }
-    },
     "run-async": {
       "version": "2.3.0",
       "resolved": "http://registry.npm.taobao.org/run-async/download/run-async-2.3.0.tgz",
@@ -11225,15 +10628,6 @@
       "resolved": "http://registry.npm.taobao.org/sax/download/sax-1.2.4.tgz",
       "integrity": "sha1-KBYjTiN4vdxOU1T6tcqold9xANk="
     },
-    "scheduler": {
-      "version": "0.13.6",
-      "resolved": "http://registry.npm.taobao.org/scheduler/download/scheduler-0.13.6.tgz",
-      "integrity": "sha1-RmpOwzJGezGpG5v3TlNHBy5M2Ik=",
-      "requires": {
-        "loose-envify": "^1.1.0",
-        "object-assign": "^4.1.1"
-      }
-    },
     "schema-utils": {
       "version": "0.3.0",
       "resolved": "http://registry.npm.taobao.org/schema-utils/download/schema-utils-0.3.0.tgz",
@@ -11406,11 +10800,6 @@
         "safe-buffer": "^5.0.1"
       }
     },
-    "shallow-equal": {
-      "version": "1.1.0",
-      "resolved": "http://registry.npm.taobao.org/shallow-equal/download/shallow-equal-1.1.0.tgz",
-      "integrity": "sha1-zAIvAw3LoNHBmKv2WKPGx0Thcco="
-    },
     "shallowequal": {
       "version": "1.1.0",
       "resolved": "http://registry.npm.taobao.org/shallowequal/download/shallowequal-1.1.0.tgz",
@@ -11934,11 +11323,6 @@
       "resolved": "http://registry.npm.taobao.org/strict-uri-encode/download/strict-uri-encode-1.1.0.tgz",
       "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM="
     },
-    "string-convert": {
-      "version": "0.2.1",
-      "resolved": "http://registry.npm.taobao.org/string-convert/download/string-convert-0.2.1.tgz",
-      "integrity": "sha1-aYLMMEn7tM2F+LJFaLnZvznu/5c="
-    },
     "string-length": {
       "version": "1.0.1",
       "resolved": "http://registry.npm.taobao.org/string-length/download/string-length-1.0.1.tgz",
@@ -12248,11 +11632,6 @@
       "resolved": "http://registry.npm.taobao.org/tiny-warning/download/tiny-warning-1.0.2.tgz",
       "integrity": "sha1-Hfrnce4aBDlr394no63OvGtkiyg="
     },
-    "tinycolor2": {
-      "version": "1.4.1",
-      "resolved": "http://registry.npm.taobao.org/tinycolor2/download/tinycolor2-1.4.1.tgz",
-      "integrity": "sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g="
-    },
     "tmp": {
       "version": "0.0.33",
       "resolved": "http://registry.npm.taobao.org/tmp/download/tmp-0.0.33.tgz",
@@ -12314,11 +11693,6 @@
         }
       }
     },
-    "toggle-selection": {
-      "version": "1.0.6",
-      "resolved": "http://registry.npm.taobao.org/toggle-selection/download/toggle-selection-1.0.6.tgz",
-      "integrity": "sha1-bkWxJj8gF/oKzH2J14sVuL932jI="
-    },
     "toposort": {
       "version": "1.0.7",
       "resolved": "http://registry.npm.taobao.org/toposort/download/toposort-1.0.7.tgz",
diff --git a/public/react/public/css/edu-all.css b/public/react/public/css/edu-all.css
index 425255048..cb78f8e00 100644
--- a/public/react/public/css/edu-all.css
+++ b/public/react/public/css/edu-all.css
@@ -3048,7 +3048,7 @@ a.singlepublishtwo{
 /*工程认证*/
 /*首页*/
 .authMainImg{width: 100%;height: 240px;background:url("/images/educoder/auth/banner1.jpg") no-repeat top center;background-size: 100% 100%;justify-content: center;align-items: center;display: -webkit-flex;}
-.ListTableLine>p,.ListTableLine>.ListTableTitle{padding: 0px 30px;background-color: #F5F5F5;line-height: 40px;height: 56px;padding-top: 8px;box-sizing: border-box;}
+.ListTableLine>p,.ListTableLine>.ListTableTitle{margin-bottom: 0px;padding: 0px 30px;background-color: #F5F5F5;line-height: 40px;height: 56px;padding-top: 8px;box-sizing: border-box;}
 .ListTableLine>p span,.ListTableTitle span{float: left;color: #666;box-sizing: border-box}
 .ListTableLine li{min-height: 48px;padding: 10px 0px;box-sizing: border-box;margin:0px 30px;border-bottom: 1px solid #eaeaea;}
 .ListTableLine li>span{float: left;box-sizing: border-box;}
diff --git a/public/react/public/index.html b/public/react/public/index.html
index 0e20a982a..a2d09dedc 100755
--- a/public/react/public/index.html
+++ b/public/react/public/index.html
@@ -5,13 +5,9 @@
     <!-- width=device-width, initial-scale=1 , shrink-to-fit=no -->
     <!-- <meta name="viewport" content=""> -->
     <meta name="theme-color" content="#000000">
-    <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
+    <!--<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">-->
+    <!--<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">-->
 
-
-      <!--
-        manifest.json provides metadata used when your web app is added to the
-        homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
-      -->
     <link rel="manifest" href="%PUBLIC_URL%/manifest.json">
     <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
     <!--
diff --git a/public/react/src/modules/courses/Index.js b/public/react/src/modules/courses/Index.js
index 95927893d..f9f80a9da 100644
--- a/public/react/src/modules/courses/Index.js
+++ b/public/react/src/modules/courses/Index.js
@@ -315,9 +315,33 @@ class CoursesIndex extends Component{
         if(isNaN(id)){
             return
         }
+
+      const querys = this.props.location.search;
+      var dataqueryss={}
+      try {
+        var foqus=this.foo(querys);
+        if(JSON.stringify(foqus) ==="{}"){
+          this.setState({
+            dataquerys:{},
+          });
+        }else{
+          this.setState({
+            dataquerys:foqus,
+          });
+          dataqueryss=foqus;
+        }
+      }catch (e) {
+        this.setState({
+          dataquerys:{},
+        })
+      }
         // let id=this.props.match.params.coursesId;
         let url ="/courses/"+id+"/left_banner.json"
-        axios.get(url).then((response) => {
+        axios.get(url,
+          {params:
+            dataqueryss
+          }
+          ).then((response) => {
             if(response!=undefined){
                 if(response.data&&response.data){
                     this.setState({
@@ -330,7 +354,28 @@ class CoursesIndex extends Component{
                 }
             }
         })
-    }
+    };
+  foo=(url)=> {
+    var json = {};
+    var regExp = /[\?\&](\w+)(=?)(\w*)/g;
+    var arr;
+    do {
+      arr = regExp.exec(url);
+      // console.log(arr); // arr = [完整的字符串, key, 等号或'', value或'']
+
+      if (arr) {
+        var key = arr[1];
+        var value = arr[3];
+        // arr[2] === ''时, value = undefined
+        if (!arr[2])
+          value = undefined;
+
+        json[key] = value;
+      }
+    } while (arr);
+
+    return json;
+  };
 
     locationNav=(list)=>{
       if(list){
diff --git a/public/react/src/modules/courses/busyWork/CommonWorkDetailIndex.js b/public/react/src/modules/courses/busyWork/CommonWorkDetailIndex.js
index b5fb8b047..8985aa07e 100644
--- a/public/react/src/modules/courses/busyWork/CommonWorkDetailIndex.js
+++ b/public/react/src/modules/courses/busyWork/CommonWorkDetailIndex.js
@@ -286,8 +286,8 @@ class CommonWorkDetailIndex extends Component{
                     seeworks={undefined}
                     reviseAttachmentUrl={`/student_works/${work_id || studentWorkId}/revise_attachment.json`}
                   />:""}
-                  <a className={"fr color-blue font-16 mt7"} href={"javascript:void(0)"}
-                    onClick={this.addAccessory}
+                  <a className={"fr color-blue font-16 "} href={"javascript:void(0)"}
+                    onClick={this.addAccessory} style={{ 'marginTop': '-4px' }}
                   >补交附件</a>
                 </React.Fragment>
 
diff --git a/public/react/src/modules/courses/busyWork/CommonWorkList.js b/public/react/src/modules/courses/busyWork/CommonWorkList.js
index a489e7c3d..56ae40e2d 100644
--- a/public/react/src/modules/courses/busyWork/CommonWorkList.js
+++ b/public/react/src/modules/courses/busyWork/CommonWorkList.js
@@ -640,6 +640,8 @@ class CommonWorkList extends Component{
     } else if (time_status === 4) {
       timeMsg = '申诉剩余时间'
     }
+
+    const hasData = student_works && !!student_works.length && page == 1
     
     // console.log(StudentData)
 		// console.log(student_works)
@@ -691,7 +693,7 @@ class CommonWorkList extends Component{
             }
           `}</style>
           <div style={{ background: '#fff'}} className="workListContent">
-             { isAdmin && <ul className="clearfix" style={{padding: "20px 40px 10px", position: 'relative', paddingLeft: '24px'}}>
+             { isAdmin && hasData && <ul className="clearfix" style={{padding: "20px 40px 10px", position: 'relative', paddingLeft: '24px'}}>
 
               <CheckAllGroup options={options_teacher_comment} label={'你的评阅:'} onChange={this.teacherCommentOptionChange}></CheckAllGroup>
               <CheckAllGroup options={options_status} label={'作品状态:'} onChange={this.statusOptionChange}></CheckAllGroup>
@@ -713,7 +715,7 @@ class CommonWorkList extends Component{
 
             { <div id="graduation_work_list" style={{padding: isStudent ? '10px 24px 10px 24px' : '0px 24px 10px 24px'}}>
               <div className="clearfix">
-                <span className="fl color-grey-6 font-12">
+                {hasData && <span className="fl color-grey-6 font-12">
                   { isAdmin ?
                     (!!all_member_count) && <React.Fragment>
                       <span className="color-orange-tip">{work_count || '0'}</span>个检索结果({all_member_count} 学生)
@@ -725,7 +727,7 @@ class CommonWorkList extends Component{
                       <span className="color-orange-tip">{left_time.time}</span>
                     </React.Fragment>
                   }
-                </span>
+                </span>}
                 
                 {/* { isAdminOrStudent && student_works && !!student_works.length && <div className="fr color-grey-6 edu-menu-panel">
                   <p style={{color: '#989898'}} className="color-grey-6"><a data-remote="true" className="font-12">
diff --git a/public/react/src/modules/courses/busyWork/common/WorkDetailPageHeader.js b/public/react/src/modules/courses/busyWork/common/WorkDetailPageHeader.js
index c9d99696a..cccaa3ca4 100644
--- a/public/react/src/modules/courses/busyWork/common/WorkDetailPageHeader.js
+++ b/public/react/src/modules/courses/busyWork/common/WorkDetailPageHeader.js
@@ -125,8 +125,8 @@ class WorkDetailPageHeader extends Component{
 										seeworks={undefined}
                     reviseAttachmentUrl={`/student_works/${work_id || studentWorkId}/revise_attachment.json`}
                   />:""}
-                  <a className={"fr color-blue font-16 mt7"} href={"javascript:void(0)"}
-                    onClick={this.addAccessory}
+                  <a className={"fr color-blue font-16 "} href={"javascript:void(0)"}
+                    onClick={this.addAccessory} style={{ 'marginTop': '-4px' }}
                   >补交附件</a>
                 </React.Fragment>
 
diff --git a/public/react/src/modules/courses/common/comments/CCommentItem.js b/public/react/src/modules/courses/common/comments/CCommentItem.js
index 2415dd0b0..5d904a36b 100644
--- a/public/react/src/modules/courses/common/comments/CCommentItem.js
+++ b/public/react/src/modules/courses/common/comments/CCommentItem.js
@@ -238,7 +238,8 @@ class CCommentItem extends Component{
 
 								<div className="comment_content  clearfix" id={`reply_content_${item.id}`}>
 									<div className="color-grey-3" id={`reply_content_${item.id}`}>
-										<div  className={"break_word_comments markdown-body"} dangerouslySetInnerHTML={{__html: item.content}}></div>
+										<div  className={"break_word_comments markdown-body"} 
+												dangerouslySetInnerHTML={{__html: this.parseCommentContent(item.content)}}></div>
 										<div className="cl"></div>
 									</div>
 								</div>
@@ -373,8 +374,8 @@ class CCommentItem extends Component{
 										</Tooltip>
 									: ''} */}
 								</div>
-								{/* style={{ height: '130px'}} */}
-								<p className="orig_reply" >
+								{/* 去掉了orig_reply 影响到i标签 */}
+								<p className="" >
                     				{/* 第二排右侧按钮区域 */}
 									{/* ${this.state.show_reply ? '回复' : '申诉'} */}
 									{(show_reply || show_appeal) && 
diff --git a/public/react/src/modules/courses/coursesDetail/CoursesBanner.js b/public/react/src/modules/courses/coursesDetail/CoursesBanner.js
index 21ac26727..437471436 100644
--- a/public/react/src/modules/courses/coursesDetail/CoursesBanner.js
+++ b/public/react/src/modules/courses/coursesDetail/CoursesBanner.js
@@ -94,9 +94,30 @@ class CoursesBanner extends Component {
 		this.updatabanner()
 	}
   updatabanner=()=>{
+    const query = this.props.location.search;
+    var dataqueryss={}
+    try {
+      var foqus=this.foo(query);
+      if(JSON.stringify(foqus) ==="{}"){
+        this.setState({
+          dataquerys:{},
+        });
+      }else{
+        this.setState({
+          dataquerys:foqus,
+        });
+        dataqueryss=foqus;
+      }
+    }catch (e) {
+      this.setState({
+        dataquerys:{},
+      })
+    }
       let courseId = this.props.match.params.coursesId;
       let url = "/courses/" + courseId + "/top_banner.json"
-      axios.get(url).then((result) => {
+      axios.get(url,{params:
+        dataqueryss
+      }).then((result) => {
       	if( result!=undefined){
 					let data = result.data;
             this.setState({
@@ -107,7 +128,28 @@ class CoursesBanner extends Component {
 					this.onloadupdatabanner()
 				}
       })
-  }
+  };
+  foo=(url)=> {
+    var json = {};
+    var regExp = /[\?\&](\w+)(=?)(\w*)/g;
+    var arr;
+    do {
+      arr = regExp.exec(url);
+      // console.log(arr); // arr = [完整的字符串, key, 等号或'', value或'']
+
+      if (arr) {
+        var key = arr[1];
+        var value = arr[3];
+        // arr[2] === ''时, value = undefined
+        if (!arr[2])
+          value = undefined;
+
+        json[key] = value;
+      }
+    } while (arr);
+
+    return json;
+  };
     showeditmenu = () => {
         this.setState({
             show: true,
diff --git a/public/react/src/modules/courses/gradinforms/myysleduinforms.css b/public/react/src/modules/courses/gradinforms/myysleduinforms.css
index b1efc783f..8376c63c8 100644
--- a/public/react/src/modules/courses/gradinforms/myysleduinforms.css
+++ b/public/react/src/modules/courses/gradinforms/myysleduinforms.css
@@ -58,7 +58,7 @@
     float: left;
     padding-top: 31px;
     padding-left: 25px;
-    font-size: 16px;
+    font-size: 21px;
     color: #05101A;
     text-align: left;
     font-weight:bold;
diff --git a/public/react/src/modules/courses/shixunHomework/ShixunWorkReport.js b/public/react/src/modules/courses/shixunHomework/ShixunWorkReport.js
index bb8ccae4a..2667f1dd9 100644
--- a/public/react/src/modules/courses/shixunHomework/ShixunWorkReport.js
+++ b/public/react/src/modules/courses/shixunHomework/ShixunWorkReport.js
@@ -349,7 +349,7 @@ class ShixunWorkReport extends Component {
 									<span className={"color-grey-9"}>	{data&&data.course_name}</span>
 							</a>
 							<span className="color-grey-9 fl ml3 mr3">&gt;</span>
-							<a className="btn colorgrey fl hovercolorblue " to={"/courses/"+this.props.match.params.coursesId+"/"+this.state.shixuntypes+"/"+category_id}>
+							<a className="btn colorgrey fl hovercolorblue " href={"/courses/"+this.props.match.params.coursesId+"/"+this.state.shixuntypes+"/"+category_id}>
 									<span className={"color-grey-9"}>{data===undefined?"":data.category===null?"":data.category.category_name}</span>
 							</a>
 							<span className="color-grey-9 fl ml3 mr3">&gt;</span>
diff --git a/public/react/src/modules/ecs/EcSetting/CourseSupports/ecCourseSupports.css b/public/react/src/modules/ecs/EcSetting/CourseSupports/ecCourseSupports.css
index 7f497b28e..87f87fc8e 100644
--- a/public/react/src/modules/ecs/EcSetting/CourseSupports/ecCourseSupports.css
+++ b/public/react/src/modules/ecs/EcSetting/CourseSupports/ecCourseSupports.css
@@ -355,4 +355,10 @@ input{
 .editlybuttonbox{
     margin-bottom: 30px;
     margin-right: 3%;
+}
+
+.Importclassroomdata{
+    top: 30px;
+    position: absolute;
+    right: 0px;
 }
\ No newline at end of file
diff --git a/public/react/src/modules/ecs/EcSetting/CourseSupports/index.js b/public/react/src/modules/ecs/EcSetting/CourseSupports/index.js
index bc848b209..511a0da64 100644
--- a/public/react/src/modules/ecs/EcSetting/CourseSupports/index.js
+++ b/public/react/src/modules/ecs/EcSetting/CourseSupports/index.js
@@ -34,7 +34,13 @@ class CourseSupports extends Component {
             Supportslist:'',
             Supportssum:false,
             Supportsclass:false,
-					  Supportsclasskey:undefined
+					  Supportsclasskey:undefined,
+				   	neweditcourse:[{"weights": 0,
+							"ec_course_name":'',
+							"top_relation": false,
+							"ec_course_id":''
+						}],
+					max_support_count:0
         }
     }
 
@@ -58,15 +64,25 @@ class CourseSupports extends Component {
         axios.get(url)
 				.then((response) => {
 						if(response.status===200){
-								this.setState({
-										data:response.data
-								})
-							  console.log(response.data.graduation_subitems.length)
 								if(response.data.graduation_subitems.length===0){
 									this.setState({
 										Supportstype:true,
+										data:response.data,
 										Supportslist:'数据为空,请去毕业要求——>毕业要求指标点分解列表配置数据'
 									})
+								}else{
+									let datas=response.data.graduation_subitems;
+									let listlength=[]
+									 datas.map((item,key)=>{
+										 listlength.push(item.course_supports.length)
+									 })
+
+								 let max_support_count=Math.max(...listlength);
+
+									this.setState({
+										max_support_count:max_support_count,
+										data:response.data
+									})
 								}
 						}
 
@@ -108,7 +124,7 @@ class CourseSupports extends Component {
         id=parseInt(id);
 
         let subindex =e.target.getAttribute("subindex");
-       debugger
+
         // const url = `/ec_course_supports/edit_require_vs_course?subitem_id=`+id
         // axios.get(url)
         //     .then((response) => {
@@ -155,14 +171,18 @@ class CourseSupports extends Component {
 					if(item.course_supports.length>0){
 						this.setState({
 							editcourse:item.course_supports,
+							neweditcourse:item.course_supports,
 							Editkey:key,
 							index:subindex,
+							ec_graduation_subitem_id:id,
 						})
 					}else if(item.course_supports.length===0){
 						this.setState({
 							editcourse:[{weights: 0,top_relation: false,ec_course_name:'',ec_course_id:''}],
+							neweditcourse:[{weights: 0,top_relation: false,ec_course_name:'',ec_course_id:''}],
 							Editkey:key,
 							index:subindex,
+							ec_graduation_subitem_id:id,
 						})
 					}
 
@@ -197,7 +217,12 @@ class CourseSupports extends Component {
 
     Addcourse=(e)=>{
         let {editcourse} =this.state;
-        let neweditcourse=editcourse;
+				let arr=new Array();
+				editcourse.map((item,key)=>{
+					arr.push(item)
+				})
+
+        let neweditcourse=arr;
         let newadd = {weights: 0,top_relation: false,ec_course_name:'',ec_course_id:''};
         neweditcourse.push(newadd);
         this.setState({
@@ -215,29 +240,49 @@ class CourseSupports extends Component {
         // 删除
         // let id =e.target.getAttribute("index");
         let {editcourse} = this.state;
-        let neweditcourse=editcourse;
-        neweditcourse.splice(e,1);
-        let newnum=0;
-        for(var j=0;j<neweditcourse.length;j++){
-            if(neweditcourse[j].weights===undefined){
-                newnum=0
-            }else{
-                newnum=newnum+neweditcourse[j].weights;
-            }
-        }
-        newnum= Math.round(newnum*100)/100;
-        this.setState({
-            Supportstype:false,
-            supportid:null,
-            Supportslist:"",
-            editcourse:neweditcourse,
-            editnum:newnum
-        })
+        let arr=new Array();
+				editcourse.map((item,key)=>{
+					arr.push(item)
+				})
+
+        let neweditcourse=arr;
+			if(neweditcourse.length>1){
+				neweditcourse.splice(e,1);
+				let newnum=0;
+				for(var j=0;j<neweditcourse.length;j++){
+					if(neweditcourse[j].weights===undefined){
+						newnum=0
+					}else{
+						newnum=newnum+neweditcourse[j].weights;
+					}
+				}
+				newnum= Math.round(newnum*100)/100;
+
+				this.setState({
+					Supportstype:false,
+					supportid:null,
+					Supportslist:"",
+					editcourse:neweditcourse,
+					editnum:newnum
+				})
+			}else{
+				this.setState({
+					// Supportstype:true,
+					Supportslist:'删除失败,至少保留一个课程',
+				})
+			}
+
+
     }
 
     enterweight=(e)=>{
         let {editcourse} = this.state;
-        let neweditcourse=editcourse;
+				let arr=new Array();
+				editcourse.map((item,key)=>{
+					arr.push(item)
+				})
+
+        let neweditcourse=arr;
         var id=e.target.id;
         var value=parseFloat(e.target.value);
         if(isNaN(value)){
@@ -301,9 +346,15 @@ class CourseSupports extends Component {
     handleChange=(e)=> {
 
         let {editcourse} = this.state;
-        let value=`${e[0]}`;
-        value=parseInt(value)
-        let neweditcourse=editcourse;
+
+				let arr=new Array();
+				editcourse.map((item,key)=>{
+					arr.push(item)
+				})
+        let neweditcourse=arr;
+
+				let value=`${e[0]}`;
+				value=parseInt(value)
         let num=`${e[1]}`;
         num=parseInt(num)
 
@@ -327,7 +378,13 @@ class CourseSupports extends Component {
     relevancetop=(e)=>{
 
         let {editcourse} = this.state;
-        let neweditcourse=editcourse;
+
+				let arr=new Array();
+				editcourse.map((item,key)=>{
+					arr.push(item)
+				})
+
+        let neweditcourse=arr;
         let id =e.target.getAttribute("itindex");
         for(var i=0;i<1;i++){
             neweditcourse[id].top_relation=false;
@@ -339,7 +396,11 @@ class CourseSupports extends Component {
     relevancebottom=(e)=>{
 
         let {editcourse} = this.state;
-        let neweditcourse=editcourse;
+				let arr=new Array();
+				editcourse.map((item,key)=>{
+					arr.push(item)
+				})
+        let neweditcourse=arr;
         let id =e.target.getAttribute("itindex");
         for(var i=0;i<1;i++){
             neweditcourse[id].top_relation=true;
@@ -355,14 +416,20 @@ class CourseSupports extends Component {
         this.inputNumberRef.blur();
     }
     CancelSupports=()=>{
+    	let{editcourse,neweditcourse}=this.state;
+				//
+				// console.log(editcourse)
+				// console.log(neweditcourse)
+
         this.setState({
             Editkey:null,
             Supportssum:false,
             Supportsclass:false,
+					  editcourse:neweditcourse
         })
     }
     SubmitClassData=()=>{
-        let {editcourse,editnum,ec_graduation_subitem_id,ec_year_id} = this.state;
+        let {editcourse,editnum,ec_graduation_subitem_id} = this.state;
         if(editcourse.length===0){
             this.setState({
                 // Supportstype:true,
@@ -409,35 +476,39 @@ class CourseSupports extends Component {
 					}
 				})
 
-        var Url = '/ec_course_supports';
+
+
+
+        var Url = `/ec_years/${this.props.match.params.ec_year_id}/graduation_course_supports.json`;
         axios.post(Url, {
-                ec_year_id: ec_year_id,
-                ec_graduation_subitem_id:ec_graduation_subitem_id,
-                course: editcourse
-            },
-            {
-                withCredentials: true
+					    	graduation_subitem_id	:ec_graduation_subitem_id,
+					    	course_supports: editcourse
             }
         ).then((response) => {
-
-            if(response.data.status===0){
-                this.setState({
-                    Editkey:null,
-                    Supportslist:response.data.messsage,
-                    Supportstype:true,
-                    Supportssum:false,
-                    Supportsclass:false,
-									  Supportsclasskey:undefined,
-                })
-                this.UpdateClassData();
+            if(response.data.id===ec_graduation_subitem_id){
+
+              //   this.setState({
+              //       Editkey:null,
+              //       Supportslist:"保存成功",
+              //       Supportstype:true,
+              //       Supportssum:false,
+              //       Supportsclass:false,
+							// 		  Supportsclasskey:undefined,
+              //   })
+							this.UpdateClassData();
+							this.setState({
+								Editkey:null,
+								Supportssum:false,
+								Supportsclass:false,
+							})
             }else if(response.data.status===-1){
-                this.setState({
-                    Supportslist:"参数错误",
-                    Supportstype:true,
-                    Supportssum:false,
-                    Supportsclass:false,
-									  Supportsclasskey:undefined,
-                })
+                // this.setState({
+                //     Supportslist:"参数错误",
+                //     Supportstype:true,
+                //     Supportssum:false,
+                //     Supportsclass:false,
+								// 	  Supportsclasskey:undefined,
+                // })
             }
         }).catch((error) => {
             console.log(error)
@@ -457,9 +528,41 @@ class CourseSupports extends Component {
             Supportslist:"",
         })
     }
+
+			confirmysl(url){
+				axios.get(url + '?export=true').then((response) => {
+					if(response.data.status&&response.data.status===-1){
+
+					}else if(response.data.status&&response.data.status===-2){
+						if(response.data.message === "100"){
+							// 已超出文件导出的上限数量(100 ),建议:
+
+							this.setState({
+								DownloadType:true,
+								DownloadMessageval:100
+							})
+						}else {
+							//因附件资料超过500M
+							this.setState({
+								DownloadType:true,
+								DownloadMessageval:500
+							})
+						}
+					}else {
+						this.props.showNotification(`正在下载中`);
+						window.open("/api"+url, '_blank');
+					}
+				}).catch((error) => {
+					console.log(error)
+				});
+			}
+
+			toforums=(url)=>{
+				window.open( url, '_blank');
+			}
     render() {
         const Option = Select.Option;
-        let {data,ec_courses_list,editcourse,editnum,index,ec_year_id,Supportsclasskey,ecComponentState,hidesupport,supportid,Editkey,titlemessage,Supportstype,Supportslist,Supportssum,Supportsclass,major_school_id} = this.state;
+        let {max_support_count,data,ec_courses_list,editcourse,editnum,index,ec_year_id,Supportsclasskey,ecComponentState,hidesupport,supportid,Editkey,titlemessage,Supportstype,Supportslist,Supportssum,Supportsclass,major_school_id} = this.state;
         var list = (length) => {
             var res = [];
             for(var i = 0; i < length; i++) {
@@ -472,6 +575,11 @@ class CourseSupports extends Component {
             return res
         }
 
+        let toptiebox={width: 126.6*max_support_count+"px"};
+
+        let ismidbox={width:123.82*max_support_count+"px",margin:'0px 0px'};
+
+        // console.log(this.props.year&&this.props.year.can_manager)
         return (
             <div className="newMain clearfix">
                 <Modal
@@ -497,7 +605,7 @@ class CourseSupports extends Component {
                 </Modal>
 
 
-                <div className="educontent mb290">
+                <div className="educontent mb20">
 
 
 
@@ -506,24 +614,26 @@ class CourseSupports extends Component {
                         <div className="clearfix padding20-30 bor-bottom-greyE" style={{position:'relative'}}>
                             <span className="font-18 courseSystem">课程体系对毕业要求的支撑</span>
                             {/* <a href="javascript:void(0)" className="fr white-btn edu-blueback-btn mt4">导出培养目标</a> */}
-                            <span className={data.is_manager===false?"none":"Importclassroomdata"} style={{top: '29px'}}>
-                                <a className="white-btn edu-blueback-btn fr mb10 mr10" target="_blank" href={'/ec_major_schools/'+major_school_id+'/academic_years/'+ec_year_id+'/export_course_requirements?format=xls'}>导出课程体系支撑矩阵</a>
+
+
+                            <span className={this.props.year&&this.props.year.can_manager===false?"none":"Importclassroomdata"} style={{top: '29px'}}>
+                                <a className="white-btn edu-blueback-btn fr mb10 mr10" onClick={()=>this.confirmysl(`/ec_years/${this.props.match.params.ec_year_id}/graduation_course_supports.xlsx`)}>导出课程体系支撑矩阵</a>
                             </span>
-                            <div className="color-grey-9 mr10">用矩阵图的形式说明本专业课程体系对毕业要求的支撑关系  <a className={"color-blue"} onClick={() => window.elasticLayer(3534)} >查看详情</a></div>
+                            <div className="color-grey-9 mr10">用矩阵图的形式说明本专业课程体系对毕业要求的支撑关系  <a className={"color-blue"} onClick={() => this.toforums(`/forums/${3534}`)} >查看详情</a></div>
 
                         </div>
                         <div className="padding20-30" id="training_objective_contents">
-                            <span className="fl SystemParameters" >毕业要求指标点(<a href={data.subitems_url}><span className="Systemnum">{data.count}</span></a>)</span>
-                            <span className="fl ml20 SystemParameters">课程体系(<a href={data.course_url}><span className="Systemnum">{data.course_count}</span></a>)</span>
+                            <span className="fl SystemParameters" >毕业要求指标点(<Link to={`/ecs/major_schools/${this.props.match.params.major_school_id}/years/${this.props.match.params.ec_year_id}/graduation_requirement`}><span className="Systemnum">{data.count}</span></Link>)</span>
+                            <span className="fl ml20 SystemParameters">课程体系(<Link to={`/ecs/major_schools/${this.props.match.params.major_school_id}/years/${this.props.match.params.ec_year_id}/courses/ec_course_support_setting/1`}><span className="Systemnum">{data.course_count}</span></Link>)</span>
                         </div>
 
                     </div>
 
                     <div className="ListTableLine" id="school_major_list" style={{overflow:'auto'}}>
 
-                        <p className="clearfix" style={{width: 120*data.max_support_count>1200? 140*data.max_support_count : 1200+"px"}}>
+                        <p className="clearfix" style={toptiebox}>
                             <span className="color-666 finishtarget">毕业要求指标点</span>
-                            {list(data.max_support_count<5||data.max_support_count===undefined?5:data.max_support_count)}
+                            {data.graduation_subitems===undefined?"":list(max_support_count<5||max_support_count===undefined?5:max_support_count)}
                             <span className="column-1 operationright color-666"
                             style={{
                                 paddingLeft: '28px'
@@ -535,7 +645,7 @@ class CourseSupports extends Component {
                                 data.graduation_subitems===undefined? <Spin  delay={500} className="Spinlarge"  indicator={<Icon type="loading" style={{ fontSize: 30 }} spin />}/>:data.graduation_subitems.map((item,key)=>{
 
                                     return (
-                                        <li className={data.graduation_subitems.length===key+1?"clearfix mb10":"clearfix"}  key={key} style={{width: 120*data.max_support_count > 1134 ? 136*data.max_support_count : 1134+"px",margin: '0px 0px'}}>
+                                        <li className={data.graduation_subitems.length===key+1?"clearfix mb10":"clearfix"}  key={key} style={ismidbox}>
                                             <Tooltip placement="bottom" title={item.sequence_title}>
                                                 <span className="column-1 columnlocation" style={{display:Editkey!=key?"block":'none',width: '95px', paddingLeft: '23px'}}>{item.graduation_requirement_position+"-"+item.position}</span>
                                             </Tooltip>
@@ -550,7 +660,7 @@ class CourseSupports extends Component {
                                                             display:Editkey!=key?"block":'none',
                                                             marginRight: '-1px'
                                                         }}>
-                                                        <div data-tip-down={t.ec_course_name} className={t.top_relation===true?"DDred columnbox":"columnbox"}
+                                                        <div title={t.ec_course_name} className={t.top_relation===true?"DDred columnbox":"columnbox"}
                                                         style={{textAlign: 'center'}}
                                                         >{t.ec_course_name.length>12?t.ec_course_name.substring(0, 10)+"...":t.ec_course_name}</div>
                                                         <div className={t.top_relation===true?"DDred":""}
@@ -569,27 +679,34 @@ class CourseSupports extends Component {
                                                           <div className="width20">{Math.round(item.weights_total*100)/100===0?0:(Math.round(item.weights_total*100)/100)}</div>
                                                       </div>
                                                       <div className="left operationalter">
-                                                         {data.is_manager===false?"":<a className="editSubentry" data-tip-down="编辑">
-                                                            <i className="iconfont icon-bianjidaibeijing color-green" id={item.ec_graduation_subitem_id} subindex={item.graduation_requirement_position+"-"+item.position} onClick={this.EditSupportCourse.bind(this,key)}></i>
+                                                         {this.props.year&&this.props.year.can_manager===false?"":<a className="editSubentry" title="编辑">
+                                                            <i className="iconfont icon-bianjidaibeijing color-green" id={item.id} subindex={item.graduation_requirement_position+"-"+item.position} onClick={this.EditSupportCourse.bind(this,key)}></i>
                                                           </a>} 
                                                     </div>
                                                   </div>
 
                                               </span>
-
-                                            <p className="ListTableLine" id="school_ListTableLine" style={{width: '1134px',display:Editkey===key?"block":'none'}} >
-
-                                                <p className="clearfix SystemModifythelist">
-                                                    <span className="ml6" style={{width:'77px'}}>指标点 {index}</span>
-                                                    <span className="column-4">支撑课程</span>
-                                                    <span className="column-2 ml93">
+																					<style>
+																						{
+																							`
+																							.ListTableLine li{ background: rgb(255, 255, 255);}
+																							`
+																						}
+																					</style>
+																					{Editkey===key?
+                                            <p className="ListTableLine" id="school_ListTableLine"  style={ismidbox}  >
+																							<div style={{width: '1134px'}}>
+																								<p className="clearfix SystemModifythelist">
+																									<span className="ml6" style={{width:'77px'}}>指标点 {index}</span>
+																									<span className="column-4">支撑课程</span>
+																									<span className="column-2 ml93">
                                                       <span> 权重(∑=1)</span>
                                                       <span className="Systempoint">(精确到两位小数)</span>
                                                     </span>
-                                                    <span className="column-1 ml50">关联度最高</span>
-                                                </p>
+																									<span className="column-1 ml50">关联度最高</span>
+																								</p>
 
-                                                <div className="clearfix editorModify">
+																								<div className="clearfix editorModify">
 																									{Supportsclass===true?<style>
 																										{
 																											`
@@ -599,77 +716,75 @@ class CourseSupports extends Component {
 																											`
 																										}
 																									</style>:""}
-                                                    {
-                                                        editcourse.map((it,key)=>{
-
-                                                            return(
-                                                                <div className="mb15" key={key}>
-
-                                                                    <Select className={Supportsclasskey===key?"showredfont heightimportant":"heightimportant"} showSearch value={it.ec_course_name} onChange={this.handleChange}>
-                                                                        {
-                                                                            ec_courses_list.map((qva,qk)=>{
-                                                                                return(
-                                                                                    <Option value={[qva.id,key,qva.name]} key={[qva.id,key,qva.name]}>{qva.name}</Option>
-                                                                                )
-                                                                            })
-
-                                                                        }
-                                                                    </Select>
-                                                                    <Input
-                                                                        type="number"
-                                                                        size="large"
-                                                                        className={Supportssum===true?"inputWeight bor-red":"inputWeight"}
-                                                                        id={key}
-                                                                        value={it.weights}
-                                                                        onInput={this.enterweight.bind(this)}
-                                                                    />
-
-                                                                    <div className="SetTheAssociated">
-
-                                                                        <div className="SetTheAssociatedchild">
-
-                                                                            <i className="iconfont icon-gouxuan gouxuanbule" style={{display:it.top_relation===false?'none':'block'}} itindex={key} onClick={this.relevancetop.bind(this)}></i>
-                                                                            <i className="iconfont icon-gouxuan gouxuanwhite" style={{display:it.top_relation===false?'block':'none'}} itindex={key} onClick={this.relevancebottom.bind(this)}></i>
-
-                                                                        </div>
-
-                                                                        <div className="left operatebutton">
-                                                                            <a className="mr15 delSubentry" data-tip-down="删除">
-                                                                                <i className="iconfont icon-shanchu color-grey-c font-15" onClick={()=>this.Deletcourses(key)}></i>
-                                                                            </a>
-                                                                            <a className="newAddSubentry" data-tip-down="添加"
-                                                                               style={{display:key===editcourse.length-1?"inline-block":'none'}}
-                                                                            ><i className="iconfont icon-tianjiafangda color-green" onClick={this.Addcourse}></i></a>
-                                                                        </div>
-
-                                                                    </div>
-
-                                                                </div>
-                                                            )
-                                                        })
-                                                    }
-
-                                                </div>
-                                                <span className="c_red none ml35 color-red" id="error_tip" style={{display:Supportssum===true||Supportsclass===true?'inline':'none'}}>{Supportslist}</span>
-                                                <div className="clearfix editorModify">
+																									{
+																										editcourse.map((it,key)=>{
+
+																											return(
+																												<div className="mb15" key={key}>
+
+																													<Select className={Supportsclasskey===key?"showredfont heightimportant":"heightimportant"} showSearch value={it.ec_course_name} onChange={this.handleChange}>
+																														{
+																															ec_courses_list.map((qva,qk)=>{
+																																return(
+																																	<Option value={[qva.id,key,qva.name]} key={[qva.id,key,qva.name]}>{qva.name}</Option>
+																																)
+																															})
+
+																														}
+																													</Select>
+																													<Input
+																														type="number"
+																														size="large"
+																														className={Supportssum===true?"inputWeight bor-red":"inputWeight"}
+																														id={key}
+																														value={it.weights}
+																														onInput={this.enterweight.bind(this)}
+																													/>
+
+																													<div className="SetTheAssociated">
+
+																														<div className="SetTheAssociatedchild">
+
+																															<i className="iconfont icon-gouxuan gouxuanbule" style={{display:it.top_relation===false?'none':'block'}} itindex={key} onClick={this.relevancetop.bind(this)}></i>
+																															<i className="iconfont icon-gouxuan gouxuanwhite" style={{display:it.top_relation===false?'block':'none'}} itindex={key} onClick={this.relevancebottom.bind(this)}></i>
+
+																														</div>
+
+																														<div className="left operatebutton">
+																															{editcourse.length===1?"":<a className="mr15 delSubentry" title="删除">
+																																<i className="iconfont icon-shanchu color-grey-c font-15" onClick={()=>this.Deletcourses(key)}></i>
+																															</a>}
+																															<a className="newAddSubentry" title="添加"
+																																 style={{display:key===editcourse.length-1?"inline-block":'none'}}
+																															><i className="iconfont icon-tianjiafangda color-green" onClick={this.Addcourse}></i></a>
+																														</div>
+
+																													</div>
+
+																												</div>
+																											)
+																										})
+																									}
+
+																								</div>
+																								<span className="c_red none ml35 color-red" id="error_tip" style={{display:Supportssum===true||Supportsclass===true?'inline':'none'}}>{Supportslist}</span>
+																								<div className="clearfix editorModify">
                                                     <span className="column-1"
-                                                    style={{
-                                                        width: '580px',
-                                                        paddingLeft: '37px',
-                                                        display: 'inline-block'
-                                                    }}
-                                                    >合计: <span>{editcourse.length}</span></span>
-                                                    <span className="ml30">合计: <span>{editnum}</span></span>
-                                                </div>
-
-                                                <div className="right editlybuttonbox">
-                                                    <div className="defalutSubmitbtn fr" onClick={this.SubmitClassData}>保存</div>
-                                                    <div className="defalutCancelbtn fr mr20" onClick={this.CancelSupports}>取消</div>
-                                                </div>
-
-                                            </p>
-
-
+																													style={{
+																														width: '580px',
+																														paddingLeft: '37px',
+																														display: 'inline-block'
+																													}}
+																										>合计: <span>{editcourse.length}</span></span>
+																									<span className="ml30">合计: <span>{editnum}</span></span>
+																								</div>
+
+																								<div className="right editlybuttonbox">
+																									<div className="defalutSubmitbtn fr" onClick={this.SubmitClassData}>保存</div>
+																									<div className="defalutCancelbtn fr mr20" onClick={this.CancelSupports}>取消</div>
+																								</div>
+																							</div>
+                                            </p>:""}
                                         </li>
                                     )
                                 })
diff --git a/public/react/src/modules/home/shixunsHome.js b/public/react/src/modules/home/shixunsHome.js
index 5677193d5..bad776b89 100644
--- a/public/react/src/modules/home/shixunsHome.js
+++ b/public/react/src/modules/home/shixunsHome.js
@@ -14,13 +14,7 @@ import UpgradeModals from '../modals/UpgradeModals';
 
 import { SnackbarHOC , getImageUrl, configShareForIndex} from 'educoder';
 
-import Slider from '@icedesign/base/lib/slider';
-
-import '@icedesign/base/lib/slider/style.js';
-
-import Rating from '@icedesign/base/lib/rating';
-
-import '@icedesign/base/lib/rating/style.js';
+import { Slider ,Rating} from "@icedesign/base";
 
 import './home.css';
 
@@ -115,7 +109,15 @@ class ShixunsHome extends Component {
                 homedatalistreps.push(homedatalist.reps[homedatalist.reps.length-i-1])
             }
          }
-
+				const MyRate = ({ defaultValue, ...rest }) => {
+					let myValue = defaultValue;
+					console.log(myValue-Math.floor(myValue))
+					// if (myValue < Math.ceil(myValue)) {
+					// 	myValue = Math.floor(myValue) + 0.5;
+					// }
+
+					return <Rating {...rest} value={myValue} />;
+				};
         return (
             <div className="newMain clearfix   backFAFAFA shixunsHome">
 							{this.state.updata===undefined?"":<UpgradeModals
@@ -349,7 +351,7 @@ class ShixunsHome extends Component {
 
                                                     <p className="clearfix mt8 ml-3">
                                                             <span className="rateYoStar fl" style={{padding: '0px',height: '20px',lineHeight: '19px',cursor: 'default'}} title="">
-                                                                  <Rating key={key} value={item.score_info===null?5:item.score_info} disabled allowHalf />
+																																	<MyRate key={key} allowHalf defaultValue={item.score_info===null?5:item.score_info} disabled/>
                                                             </span>
                                                         <span className="fl ml25 font-12 color-grey-9 lineh-12 mt4">{item.score_info===null?"5分":item.score_info+"分"}</span>
                                                     </p>
diff --git a/public/react/src/modules/page/VNCContainer.js b/public/react/src/modules/page/VNCContainer.js
index 3a85976bb..6ef10888a 100644
--- a/public/react/src/modules/page/VNCContainer.js
+++ b/public/react/src/modules/page/VNCContainer.js
@@ -85,7 +85,7 @@ class VNCContainer extends Component {
     	})
 	}
 	onTreeSelect = (selectedKeys, info) => {
-		const isLeaf = info.node.props.isLeaf;
+		const isLeaf = info.node.isLeaf();
 		if (isLeaf) {		// 叶子节点
 			selectedKeys.length && this.setState({
 				fileTreeSelectedKeys: selectedKeys
diff --git a/public/react/src/modules/page/component/repo/RepoTree.js b/public/react/src/modules/page/component/repo/RepoTree.js
index fbf1286c3..102f797ef 100644
--- a/public/react/src/modules/page/component/repo/RepoTree.js
+++ b/public/react/src/modules/page/component/repo/RepoTree.js
@@ -7,7 +7,7 @@ import 'rc-tree/assets/index.css';
 
 const $ = window.$;
 export default function RepoTree(props) {
-    const { fileTreeData, onLoadData, onTreeSelect, fileTreeSelectedKeys, loadRepoFiles } = props;
+    const { fileTreeData, onLoadData, fileTreeSelectedKeys, loadRepoFiles } = props;
     const [expandedKeys, setExpandedKeys] = useState([])
     useEffect(() => {
         loadRepoFiles()
@@ -36,7 +36,19 @@ export default function RepoTree(props) {
     };
     const treeNodes = loop(fileTreeData);
     
-    
+    function onTreeSelect(selectedKeys, info) {
+        if (!info.node.isLeaf()) {
+            const _expandedKeys = expandedKeys.slice(0)
+            const _index = _expandedKeys.indexOf(selectedKeys[0]);
+            if (_index == -1) {
+                _expandedKeys.push(selectedKeys[0])    
+            } else {
+                _expandedKeys.splice( _index, 1)
+            }
+            setExpandedKeys( _expandedKeys )
+        }
+        props.onTreeSelect(selectedKeys, info)
+    }
     // selectable={false}
     return (
         <Tree
diff --git a/public/react/src/modules/page/main/CodeRepositoryView.css b/public/react/src/modules/page/main/CodeRepositoryView.css
index 1ed76a02f..b0f8eb939 100644
--- a/public/react/src/modules/page/main/CodeRepositoryView.css
+++ b/public/react/src/modules/page/main/CodeRepositoryView.css
@@ -147,4 +147,8 @@
 }
 .xterm .xterm-viewport {
 	overflow-y: auto !important;
+}
+
+.repoFilesDrawer .rc-tree {
+	user-select: none;
 }
\ No newline at end of file
diff --git a/public/react/src/modules/page/main/CodeRepositoryView.js b/public/react/src/modules/page/main/CodeRepositoryView.js
index 6da34c541..fc10a31dd 100644
--- a/public/react/src/modules/page/main/CodeRepositoryView.js
+++ b/public/react/src/modules/page/main/CodeRepositoryView.js
@@ -65,6 +65,7 @@ class CodeRepositoryView extends Component {
                     expandedKeys.push( index === 0 ? item : expandedKeys[index - 1] + '/' + item)
                 })
             }
+            expandedKeys.length = 1 // 没办法做到多级初始化
             // 初始化时无法展开到根节点 https://github.com/fis-components/rc-tree/issues/3
             expandedKeys.length && this.setState({
                 expandedKeys,
@@ -110,10 +111,23 @@ class CodeRepositoryView extends Component {
         // $('#codetab_con_1 .codemirrorBackground').hide()
         
     }
-
+    onTreeSelect = (selectedKeys, info) => {
+        if (!info.node.isLeaf()) {
+            const expandedKeys = this.state.expandedKeys.slice(0)
+            const _index = expandedKeys.indexOf(selectedKeys[0]);
+            if (_index == -1) {
+                expandedKeys.push(selectedKeys[0])    
+            } else {
+                expandedKeys.splice( _index, 1)
+            }
+            this.setState({ expandedKeys })
+        }
+        
+        this.props.onTreeSelect(selectedKeys, info)
+    }   
     buildTree() {
         // TODO http://localhost:3007/tasks/xgffnuomytpj   这个实训没有文件树
-        const { fileTreeData, onLoadData, onTreeSelect, fileTreeSelectedKeys } = this.props;
+        const { fileTreeData, onLoadData, fileTreeSelectedKeys } = this.props;
         if (!fileTreeData || fileTreeData.length === 0) {
             return ""
         }
@@ -136,7 +150,7 @@ class CodeRepositoryView extends Component {
         return (
             <Tree
                 selectedKeys={fileTreeSelectedKeys}
-                onSelect={onTreeSelect}
+                onSelect={this.onTreeSelect}
                 onExpand={this.onExpand}
                 expandedKeys={this.state ? this.state.expandedKeys : []}
                 autoExpandParent={this.state.autoExpandParent}
diff --git a/public/react/src/modules/page/main/CodeRepositoryViewContainer.js b/public/react/src/modules/page/main/CodeRepositoryViewContainer.js
index 111ccd253..b4d9c4fcf 100644
--- a/public/react/src/modules/page/main/CodeRepositoryViewContainer.js
+++ b/public/react/src/modules/page/main/CodeRepositoryViewContainer.js
@@ -223,7 +223,7 @@ class CodeRepositoryViewContainer extends Component {
 		  	});
 	}
 	onTreeSelect = (selectedKeys, info) => {
-		const isLeaf = info.node.props.isLeaf;
+		const isLeaf = info.node.isLeaf();
 		if (isLeaf) {		// 叶子节点
 			selectedKeys.length && this.setState({
 				fileTreeSelectedKeys: selectedKeys
diff --git a/public/react/src/modules/tpm/TPMBanner.js b/public/react/src/modules/tpm/TPMBanner.js
index 997786db2..7b094a642 100644
--- a/public/react/src/modules/tpm/TPMBanner.js
+++ b/public/react/src/modules/tpm/TPMBanner.js
@@ -6,7 +6,9 @@ import {BrowserRouter as Router, Route, Link, Switch} from "react-router-dom";
 
 import PropTypes from 'prop-types';
 
-import {Modal,Input,Radio,Pagination,message,Spin,Icon,Tooltip} from 'antd';
+import { Rating ,Progress} from "@icedesign/base";
+
+import {Modal,Input,Radio,Pagination,message,Spin,Icon,Tooltip,Rate} from 'antd';
 
 import AccountProfile from"../user/AccountProfile";
 
@@ -16,17 +18,6 @@ import axios from 'axios'
 
 import Modals from '../modals/Modals';
 
-// import { Rating,Progress } from '@icedesign/base';
-
-import Rating from '@icedesign/base/lib/rating';
-
-import Progress from '@icedesign/base/lib/progress';
-
-// 引入业务组件样式
-import '@icedesign/base/lib/rating/style.js';
-
-import '@icedesign/base/lib/progress/style.js';
-
 import './shixuns/css/TPMBanner.css';
 
 let $ = window.$;
@@ -578,6 +569,15 @@ class TPMBanner extends Component {
         };
 
 			  const antIcon = <Icon type="loading" style={{ fontSize: 24 }} spin />;
+		const MyRate = ({ defaultValue, ...rest }) => {
+			let myValue = defaultValue;
+			console.log(myValue-Math.floor(myValue))
+			// if (myValue < Math.ceil(myValue)) {
+			// 	myValue = Math.floor(myValue) + 0.5;
+			// }
+
+			return <Rating {...rest} value={myValue} />;
+		};
       	return (
 
                 shixunsDetails===undefined?"":
@@ -616,7 +616,22 @@ class TPMBanner extends Component {
 
             </p>
             <div className="clearfix mt50">
-                <ul className="fl color-grey-c pathInfo">
+							{/*<style>*/}
+								{/*{*/}
+									{/*`*/}
+									{/*.anticon-star{*/}
+									  {/*font-size:14px;*/}
+									{/*}*/}
+									{/*.pathInfo{*/}
+									  {/*margin-right:-5px;*/}
+									{/*}*/}
+									{/*.ant-rate{*/}
+										{/*color: #FFA800;*/}
+									{/*}*/}
+									{/*`*/}
+								{/*}*/}
+							{/*</style>*/}
+                <ul className="fl color-grey-c pathInfo" >
                     <li>
                         <span>学习人数</span>
                         <span className="mt10">{shixunsDetails.stu_num}</span>
@@ -633,11 +648,11 @@ class TPMBanner extends Component {
                 </ul>
 
                 <div className="pr fl" id="commentsStar" onMouseOver={()=>this.showonMouseOver()} onMouseOut={()=>this.hideonMouseOut()}>
-									  <div className={"color-grey-c mb11"} style={{color: "#Fff",textAlign: "center"}}>学员评分</div>
+									  <div className={"color-grey-c  ml15"} style={{color: "#Fff",textAlign: "center"}}>学员评分</div>
                     <div className="rateYo">
-                        <Rating value={star_info[0]} disabled allowHalf/>
+											<MyRate allowHalf defaultValue={star_info[0]} disabled/>
                     </div>
-                    <div id="ratePanel" className="showratePanel" style={{"width":"512px"}} onMouseOut={()=>this.hideonMouseOut()}>
+                    <div id="ratePanel" className="showratePanel" style={{"width":"530px"}} onMouseOut={()=>this.hideonMouseOut()}>
                         <div className="pr">
                             <span className="rateTrangle"></span>
                             <div className="pr clearfix ratePanelContent" style={{height: '177px'}}>
@@ -648,16 +663,16 @@ class TPMBanner extends Component {
                                         <span className="displayblock">总评分</span>
                                         <div className="rateYo">
                                             {showradios === true ?
-                                                <Rating value={star_info[0]} allowHalf/>
+																							<MyRate allowHalf defaultValue={star_info[0]} disabled/>
                                                 : ""}
                                         </div>
                                     </div>
                                 </div>
-                                <div className="fr width360">
+                                <div className="fr">
                                     <div className="clearfix">
                                         <div className="rateYo fl mt3">
                                             {showradios === true ?
-                                                <Rating value={5} disabled allowHalf/>
+																							<MyRate allowHalf defaultValue={5} disabled/>
                                                 : ""}
                                         </div>
                                         <Progress percent={star_infos[1]} showInfo={false}></Progress>
@@ -666,7 +681,7 @@ class TPMBanner extends Component {
                                     <div className="clearfix">
                                         <div className="rateYo fl mt3">
                                             {showradios === true ?
-                                                <Rating value={4} disabled allowHalf/>
+																							<MyRate allowHalf defaultValue={4} disabled/>
                                                 : ""}
                                         </div>
                                         <Progress percent={star_infos[2]} showInfo={false}></Progress>
@@ -675,7 +690,7 @@ class TPMBanner extends Component {
                                     <div className="clearfix">
                                         <div className="rateYo fl mt3">
                                             {showradios === true ?
-                                                <Rating value={3} disabled allowHalf/>
+																							<MyRate allowHalf defaultValue={3} disabled/>
                                                 : ""}
                                         </div>
                                         <Progress percent={star_infos[3]} showInfo={false}></Progress>
@@ -684,7 +699,7 @@ class TPMBanner extends Component {
                                     <div className="clearfix">
                                         <div className="rateYo fl mt3">
                                             {showradios === true ?
-                                                <Rating value={2} disabled allowHalf/>
+																							<MyRate allowHalf defaultValue={2} disabled/>
                                                 : ""}
                                         </div>
                                         <Progress percent={star_infos[4]} showInfo={false}></Progress>
@@ -693,7 +708,7 @@ class TPMBanner extends Component {
                                     <div className="clearfix">
                                         <div className="rateYo fl mt3">
                                             {showradios === true ?
-                                                <Rating value={1} disabled allowHalf/>
+																							<MyRate allowHalf defaultValue={1} disabled/>
                                                 : ""}
                                         </div>
                                         <Progress percent={star_infos[5]} showInfo={false}></Progress>
diff --git a/public/react/src/modules/tpm/TPMFork/TPMForklist.js b/public/react/src/modules/tpm/TPMFork/TPMForklist.js
index bbe3509a6..8cb5d2378 100644
--- a/public/react/src/modules/tpm/TPMFork/TPMForklist.js
+++ b/public/react/src/modules/tpm/TPMFork/TPMForklist.js
@@ -6,7 +6,7 @@ import {BrowserRouter as Router, Route, Link, Switch} from "react-router-dom";
 
 // import "antd/dist/antd.css";
 
-import Rating from '@icedesign/base/lib/rating';
+import { Rating } from "@icedesign/base";
 
 import axios from 'axios';
 
@@ -88,7 +88,15 @@ export default class TPMFork_listComponent extends Component {
 
     let {shixuns, total_count, shixunsID, Forkvisible, Forkcurrent} = this.state;
 
+		const MyRate = ({ defaultValue, ...rest }) => {
+			let myValue = defaultValue;
+			console.log(myValue-Math.floor(myValue))
+			// if (myValue < Math.ceil(myValue)) {
+			// 	myValue = Math.floor(myValue) + 0.5;
+			// }
 
+			return <Rating {...rest} value={myValue} />;
+		};
     return (
       <React.Fragment>
         <div className="educontent mb20">
@@ -141,9 +149,9 @@ export default class TPMFork_listComponent extends Component {
                       </p>
 
                       <p className="clearfix mt8 ml-3">
-                                                    <span className="rateYoStar fl" style={{padding: '0px',height: '20px',lineHeight: '19px',cursor: 'default'}} title="">
-                                                          <Rating key={key} value={item.score_info===null?5:item.score_info} disabled allowHalf />
-                                                    </span>
+												<span className="rateYoStar fl" style={{padding: '0px',height: '20px',lineHeight: '19px',cursor: 'default'}} title="">
+															<MyRate key={key} allowHalf defaultValue={item.score_info===null?5:item.score_info} disabled/>
+												</span>
                         <span className="fl ml25 font-12 color-grey-9 lineh-12 mt4">{item.score_info===null?"5分":item.score_info+"分"}</span>
                       </p>
 
diff --git a/public/react/src/modules/tpm/TPMShixunDiscuss.css b/public/react/src/modules/tpm/TPMShixunDiscuss.css
index 6006b3f30..3af4ec269 100644
--- a/public/react/src/modules/tpm/TPMShixunDiscuss.css
+++ b/public/react/src/modules/tpm/TPMShixunDiscuss.css
@@ -1,47 +1,47 @@
-.tpmComment .-fit {
-	position: inherit;
-}
-.tpmComment .rc-pagination {
-    margin-left: auto;
-    margin-right: auto;
-    margin-top: 12px;
-    margin-bottom: 20px;
-}
-.tpmComment .paginationSection {
-	background: #FAFAFA;
-}
-.tpmComment .comment_item_cont.df.clearfix:nth-last-child(1) {
-    border-bottom: none;
-}
-
-/*.tpmComment .fl.edu-back-white {*/
-/*min-height: 600px;*/
-/*}*/
-
-
-.user_watch_btn {
-	cursor: pointer;
-}
-
-
-/*md编辑器*/
-.tpmComment .commentItemMDEditor a.task-btn {
-    background: #4cacff!important;
-    margin-right: 16px;
-    margin-top: 16px;
-}
-/* md编辑器 resizeBar*/
- .tpmComment .commentItemMDEditor .editor__resize {
-    transform: translateX(-176%)
-}
-
-#ratePanel > div > div > div.fr div.rateYo.fl.mt3 {
-    height: 20px;
-    line-height: 20px;
-    cursor: default;
-    width: 90px;
-}
-
-.tpmComment .icon-jiangli {
-    /* margin-top: 2px; */
+.tpmComment .-fit {
+	position: inherit;
+}
+.tpmComment .rc-pagination {
+    margin-left: auto;
+    margin-right: auto;
+    margin-top: 12px;
+    margin-bottom: 20px;
+}
+.tpmComment .paginationSection {
+	background: #FAFAFA;
+}
+.tpmComment .comment_item_cont.df.clearfix:nth-last-child(1) {
+    border-bottom: none;
+}
+
+/*.tpmComment .fl.edu-back-white {*/
+/*min-height: 600px;*/
+/*}*/
+
+
+.user_watch_btn {
+	cursor: pointer;
+}
+
+
+/*md编辑器*/
+.tpmComment .commentItemMDEditor a.task-btn {
+    background: #4cacff!important;
+    margin-right: 16px;
+    margin-top: 16px;
+}
+/* md编辑器 resizeBar*/
+ .tpmComment .commentItemMDEditor .editor__resize {
+    transform: translateX(-176%)
+}
+
+#ratePanel > div > div > div.fr div.rateYo.fl.mt3 {
+    height: 20px;
+    line-height: 20px;
+    cursor: default;
+    width: 110px;
+}
+
+.tpmComment .icon-jiangli {
+    /* margin-top: 2px; */
 }
\ No newline at end of file
diff --git a/public/react/src/modules/tpm/shixuns/ShixunCard.js b/public/react/src/modules/tpm/shixuns/ShixunCard.js
index 3a0935e66..021185cc8 100644
--- a/public/react/src/modules/tpm/shixuns/ShixunCard.js
+++ b/public/react/src/modules/tpm/shixuns/ShixunCard.js
@@ -7,24 +7,15 @@ import PropTypes from 'prop-types';
 
 import classNames from 'classnames';
 
-import {getImageUrl,setImagesUrl, toPath} from 'educoder';
+import { Rating ,Pagination} from "@icedesign/base";
 
-import { Spin,Icon } from 'antd';
+import {getImageUrl,setImagesUrl, toPath} from 'educoder';
 
-import 'antd/lib/pagination/style/index.css';
+import { Spin,Icon,Tooltip ,Rate} from 'antd';
 
 import './shixunCss/shixunCard.css';
 
-import Rating from '@icedesign/base/lib/rating';
-
-import Pagination from '@icedesign/base/lib/pagination';
-
 // 引入业务组件样式
-import '@icedesign/base/lib/pagination/style.js';
-
-import '@icedesign/base/lib/rating/style.js';
-
-import { Tooltip } from 'antd';
 
 import axios from 'axios';
 
@@ -55,6 +46,15 @@ class ShixunCard extends Component {
 
   render() {
     let {middleshixundata, pagination, typepvisible, pages, totalcount} = this.props;
+		const MyRate = ({ defaultValue, ...rest }) => {
+			let myValue = defaultValue;
+			console.log(myValue-Math.floor(myValue))
+			// if (myValue < Math.ceil(myValue)) {
+			// 	myValue = Math.floor(myValue) + 0.5;
+			// }
+
+			return <Rating {...rest} value={myValue} />;
+		};
     return (
       <div className="educontent mb80">
 
@@ -78,10 +78,11 @@ class ShixunCard extends Component {
         </div>
 
         <div className="mt10 mb20 clearfix"
-             style={{display: middleshixundata === undefined || middleshixundata.length === 0 ? "none" : "block"}}>
+             // style={{display: middleshixundata === undefined || middleshixundata.length === 0 ? "none" : "block"}}
+				>
           <div className="shixun_list_content">
             <div className="square-list clearfix">
-              { middleshixundata===undefined?" ":middleshixundata.map((item,key)=>{
+              {middleshixundata === undefined || middleshixundata.length === 0?" ":middleshixundata.map((item,key)=>{
                 return(
                   <div className="square-Item" key={key} id={item.id}>
 										<style>
@@ -122,12 +123,27 @@ class ShixunCard extends Component {
                       </p>
 
 											{/*target="_blank"*/}
-
+											{/*<style>*/}
+												{/*{*/}
+													{/*`*/}
+													{/*.anticon-star{*/}
+														{/*font-size:16px;*/}
+													{/*}*/}
+													{/*.pathInfo{*/}
+														{/*margin-right:-5px;*/}
+													{/*}*/}
+													{/*.ant-rate{*/}
+														{/*color: #FFA800;*/}
+													{/*}*/}
+													{/*`*/}
+												{/*}*/}
+											{/*</style>*/}
                       <p className="clearfix mt8 ml-3">
                         <span className="rateYoStar fl" style={{padding: '0px',height: '20px',lineHeight: '19px',cursor: 'default'}} title="">
-                              <Rating key={key} value={item.score_info===null?5:item.score_info} disabled allowHalf />
+                              {/*<Rate allowHalf value={item.score_info===null?5:item.score_info} disabled key={key} />*/}
+                                <MyRate key={key} allowHalf defaultValue={item.score_info===null?5:item.score_info} disabled/>
                         </span>
-                        <span className="fl ml25 font-12 color-grey-9 lineh-12 mt4">{item.score_info===null?"5分":item.score_info+"分"}</span>
+                        <span className="fl ml25 font-12 color-grey-9 lineh-12 mt5">{item.score_info===null?"5分":item.score_info+"分"}</span>
                       </p>
 
                       <p className="clearfix mt8 font-12 color-grey-B4">
diff --git a/public/react/src/modules/tpm/shixuns/css/TPMBanner.css b/public/react/src/modules/tpm/shixuns/css/TPMBanner.css
index a6a7acc9a..fe059fccd 100644
--- a/public/react/src/modules/tpm/shixuns/css/TPMBanner.css
+++ b/public/react/src/modules/tpm/shixuns/css/TPMBanner.css
@@ -8,7 +8,7 @@
  .rateYo{
   text-align: center;
   cursor: default;
-  width: 90px;
+  width: 111px;
  }
 
  a:link, a:visited {
diff --git a/public/stylesheets/educoder/edu-all.css b/public/stylesheets/educoder/edu-all.css
index 91ea604d4..c20b648db 100644
--- a/public/stylesheets/educoder/edu-all.css
+++ b/public/stylesheets/educoder/edu-all.css
@@ -3051,7 +3051,7 @@ a.singlepublishtwo{
 /*工程认证*/
 /*首页*/
 .authMainImg{width: 100%;height: 240px;background:url("/images/educoder/auth/banner1.jpg") no-repeat top center;background-size: 100% 100%;justify-content: center;align-items: center;display: -webkit-flex;}
-.ListTableLine>p,.ListTableLine>.ListTableTitle{padding: 0px 30px;background-color: #F5F5F5;line-height: 40px;height: 56px;padding-top: 8px;box-sizing: border-box;}
+.ListTableLine>p,.ListTableLine>.ListTableTitle{margin-bottom: 0px;padding: 0px 30px;background-color: #F5F5F5;line-height: 40px;height: 56px;padding-top: 8px;box-sizing: border-box;}
 .ListTableLine>p span,.ListTableTitle span{float: left;color: #666;box-sizing: border-box}
 .ListTableLine li{min-height: 48px;padding: 10px 0px;box-sizing: border-box;margin:0px 30px;border-bottom: 1px solid #eaeaea;}
 .ListTableLine li>span{float: left;box-sizing: border-box;}