From 8dbd405db4d008006a5d53eee84bab87528a532b Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Tue, 29 Oct 2019 17:21:08 +0800 Subject: [PATCH 01/17] =?UTF-8?q?=E5=AE=9E=E8=AE=AD=E4=BD=9C=E4=B8=9A?= =?UTF-8?q?=E7=9A=84=E6=80=BB=E5=88=86=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/homework_commons_controller.rb | 4 ++++ app/views/homework_commons/settings.json.jbuilder | 2 +- .../20191029084344_add_total_score_to_homework_commons.rb | 5 +++++ 3 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20191029084344_add_total_score_to_homework_commons.rb diff --git a/app/controllers/homework_commons_controller.rb b/app/controllers/homework_commons_controller.rb index 5d27de7b8..692f813a6 100644 --- a/app/controllers/homework_commons_controller.rb +++ b/app/controllers/homework_commons_controller.rb @@ -572,10 +572,13 @@ class HomeworkCommonsController < ApplicationController if @homework.homework_type == "practice" # 实训作业的评分设置 + tip_exception("总分值不能为空") if params[:total_score].blank? + tip_exception("总分值不能小于0") if params[:total_score].to_i < 0 tip_exception("缺少answer_open_evaluation参数") if params[:answer_open_evaluation].nil? tip_exception("缺少work_efficiency参数") if params[:work_efficiency].nil? tip_exception("缺少eff_score参数") if params[:work_efficiency] && params[:eff_score].blank? tip_exception("效率分不能小于等于0") if params[:eff_score] && params[:eff_score].to_i <= 0 + tip_exception("效率分不能大于总分值") if params[:eff_score] && params[:eff_score].to_i > params[:total_score].to_i tip_exception("缺少shixun_evaluation参数") if params[:shixun_evaluation].blank? tip_exception("缺少challenge_settings参数") if params[:challenge_settings].blank? # tip_exception("缺少challenge_id参数") if params[:challenge_settings][:challenge_id].blank? @@ -584,6 +587,7 @@ class HomeworkCommonsController < ApplicationController # params[:challenge_settings][:challenge_score].length != params[:challenge_settings][:challenge_id].length current_eff_score = @homework.eff_score + @homework.total_score = params[:total_score] @homework.work_efficiency = params[:work_efficiency] @homework.eff_score = params[:work_efficiency] ? params[:eff_score].to_i : 0 diff --git a/app/views/homework_commons/settings.json.jbuilder b/app/views/homework_commons/settings.json.jbuilder index 52e3f1cdf..cf36c6165 100644 --- a/app/views/homework_commons/settings.json.jbuilder +++ b/app/views/homework_commons/settings.json.jbuilder @@ -5,7 +5,7 @@ json.partial! "homework_btn_check", locals: {identity: @user_course_identity, ho json.partial! "student_btn_check", locals: {identity: @user_course_identity, homework: @homework, work: @work} json.(@homework, :unified_setting, :publish_time, :end_time, :late_penalty, :allow_late, :late_time, :work_public, - :score_open, :answer_public) + :score_open, :answer_public, :total_score) json.group_settings @course_groups do |group| json.group_id group.id diff --git a/db/migrate/20191029084344_add_total_score_to_homework_commons.rb b/db/migrate/20191029084344_add_total_score_to_homework_commons.rb new file mode 100644 index 000000000..1fefdde34 --- /dev/null +++ b/db/migrate/20191029084344_add_total_score_to_homework_commons.rb @@ -0,0 +1,5 @@ +class AddTotalScoreToHomeworkCommons < ActiveRecord::Migration[5.2] + def change + add_column :homework_commons, :total_score, :float, default: 100 + end +end From b0cba788fc799103b65c3d883072f0f706f0f52e Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Wed, 30 Oct 2019 10:34:23 +0800 Subject: [PATCH 02/17] =?UTF-8?q?=E5=AE=9E=E8=AE=AD=E4=BD=9C=E4=B8=9A?= =?UTF-8?q?=E7=9A=84=E8=B0=83=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/student_works_controller.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/controllers/student_works_controller.rb b/app/controllers/student_works_controller.rb index b7a6953a5..c45bca268 100644 --- a/app/controllers/student_works_controller.rb +++ b/app/controllers/student_works_controller.rb @@ -534,7 +534,9 @@ class StudentWorksController < ApplicationController # 作品调分 def adjust_score tip_exception("分数不能为空") if params[:score].blank? - tip_exception("分数不能超过0-100") if params[:score].to_f < 0 || params[:score].to_f > 100 + tip_exception("分数不能超过0-100") if @homework.homework_type != "practice" && (params[:score].to_f < 0 || params[:score].to_f.round(1) > 100.round(1)) + tip_exception("已提交的作品请去评阅页进行调分") if @homework.homework_type == "practice" && @work.work_status > 0 + tip_exception("分数不能超过总分值#{@homework.total_score}") if @homework.homework_type == "practice" && (params[:score].to_f < 0 || params[:score].to_f.round(1) > @homework.total_score.round(1)) ActiveRecord::Base.transaction do begin # 分数不为空的历史评阅都置为失效 From 636f0655a3b9b0be7e0d602f184236cc1d9f19b3 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Wed, 30 Oct 2019 14:44:10 +0800 Subject: [PATCH 03/17] =?UTF-8?q?=E8=AF=95=E5=8D=B7=E6=9C=AA=E6=8F=90?= =?UTF-8?q?=E4=BA=A4=E7=9A=84=E8=B0=83=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/exercises_controller.rb | 15 +++++++++++++++ app/models/exercise_user.rb | 4 +++- app/models/exercise_user_score.rb | 5 +++++ .../homework_commons/works_list.json.jbuilder | 2 +- config/routes.rb | 3 ++- .../20191030062150_create_exercise_user_scores.rb | 13 +++++++++++++ spec/models/exercise_user_score_spec.rb | 5 +++++ 7 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 app/models/exercise_user_score.rb create mode 100644 db/migrate/20191030062150_create_exercise_user_scores.rb create mode 100644 spec/models/exercise_user_score_spec.rb diff --git a/app/controllers/exercises_controller.rb b/app/controllers/exercises_controller.rb index bd5a41123..a6464a151 100644 --- a/app/controllers/exercises_controller.rb +++ b/app/controllers/exercises_controller.rb @@ -605,6 +605,21 @@ class ExercisesController < ApplicationController end end + # 对未提交的用户进行调分 + def adjust_score + exercise_user = @exercise.exercise_users.find_by!(user_id: params[:user_id]) + tip_exception("已提交的作品请去评阅页进行调分") if exercise_user.commit_status == 1 + tip_exception("分数不能为空") if params[:score].blank? + tip_exception("分数不能超过0-#{@exercise.question_scores}") if params[:score].to_f < 0 || params[:score].to_f.round(1) > @exercise.question_scores.round(1) + + ActiveRecord::Base.transaction do + start_at_time = exercise_user.start_at || Time.now + exercise_user.update_attributes!(start_at: start_at_time, end_at: Time.now, status: 1, commit_status: 1, score: params[:score].to_f.round(2), commit_method: 5) + ExerciseUserScore.create!(exercise_id: @exercise.id, exercise_user_id: exercise_user.id, score: params[:score], comment: params[:comment]) + normal_status("操作成功") + end + end + #我的题库 def my_exercises ActiveRecord::Base.transaction do diff --git a/app/models/exercise_user.rb b/app/models/exercise_user.rb index 0f2e8456e..fb2034998 100644 --- a/app/models/exercise_user.rb +++ b/app/models/exercise_user.rb @@ -1,8 +1,10 @@ class ExerciseUser < ApplicationRecord - # commit_method 0 为默认, 1为学生的手动提交,2为倒计时结束后自动提交,3为试卷定时截止的自动提交, 4为教师手动的立即截止 + # commit_method 0 为默认, 1为学生的手动提交,2为倒计时结束后自动提交,3为试卷定时截止的自动提交, 4为教师手动的立即截止, 5为老师调分 belongs_to :user belongs_to :exercise + has_many :exercise_user_scores, dependent: :destroy + scope :commit_exercise_by_status, lambda { |s| where(commit_status: s) } scope :exercise_user_committed, -> {where("commit_status != ?",0) } scope :current_exercise_user, lambda { |user_id,exercise_id| where(user_id: user_id,exercise_id:exercise_id)} diff --git a/app/models/exercise_user_score.rb b/app/models/exercise_user_score.rb new file mode 100644 index 000000000..d022b0b31 --- /dev/null +++ b/app/models/exercise_user_score.rb @@ -0,0 +1,5 @@ +class ExerciseUserScore < ApplicationRecord + belongs_to :exercise + belongs_to :exercise_user + belongs_to :user +end diff --git a/app/views/homework_commons/works_list.json.jbuilder b/app/views/homework_commons/works_list.json.jbuilder index 24d1f354a..3807d5b99 100644 --- a/app/views/homework_commons/works_list.json.jbuilder +++ b/app/views/homework_commons/works_list.json.jbuilder @@ -86,7 +86,7 @@ if @homework.homework_type == "practice" json.work_efficiency @homework.work_efficiency json.student_works @student_works.each do |work| - json.(work, :id, :work_status, :update_time, :ultimate_score) + json.(work, :id, :work_status, :update_time, :ultimate_score, :myshixun_id) json.late_penalty work.late_penalty if @homework.allow_late json.work_score work_score_format(work.work_score, @current_user == work.user, @score_open) diff --git a/config/routes.rb b/config/routes.rb index 2f8f3d958..5315df7ce 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -510,7 +510,7 @@ Rails.application.routes.draw do post :join_exercise_banks # 加入习题集 post :publish # 立即发布 post :end_exercise # 立即截止 - +`` end end @@ -626,6 +626,7 @@ Rails.application.routes.draw do post :cancel_exercise get :begin_commit #提交前的弹窗 get :publish_groups + post :adjust_score end resources :exercise_questions,only:[:new,:create,:index] end diff --git a/db/migrate/20191030062150_create_exercise_user_scores.rb b/db/migrate/20191030062150_create_exercise_user_scores.rb new file mode 100644 index 000000000..911a8a3a5 --- /dev/null +++ b/db/migrate/20191030062150_create_exercise_user_scores.rb @@ -0,0 +1,13 @@ +class CreateExerciseUserScores < ActiveRecord::Migration[5.2] + def change + create_table :exercise_user_scores do |t| + t.references :exercise, index: true + t.references :exercise_user, index: true + t.float :score + t.text :comment + t.references :user, index: true + + t.timestamps + end + end +end diff --git a/spec/models/exercise_user_score_spec.rb b/spec/models/exercise_user_score_spec.rb new file mode 100644 index 000000000..97f67a99a --- /dev/null +++ b/spec/models/exercise_user_score_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe ExerciseUserScore, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end From 1fa703cf81b6c1026452d0fa156d3a699072a724 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Thu, 31 Oct 2019 16:39:03 +0800 Subject: [PATCH 04/17] =?UTF-8?q?=E8=AF=BE=E5=A0=82=E6=A8=A1=E5=BC=8F?= =?UTF-8?q?=E7=9A=84=E7=AB=9E=E8=B5=9B=E6=8A=A5=E5=90=8D=E6=95=B0=E7=BB=9F?= =?UTF-8?q?=E8=AE=A1=E6=9C=89=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/competitions/competitions_controller.rb | 2 +- app/views/competitions/competitions/index.json.jbuilder | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/controllers/competitions/competitions_controller.rb b/app/controllers/competitions/competitions_controller.rb index 1a80dc7e6..31ed4367d 100644 --- a/app/controllers/competitions/competitions_controller.rb +++ b/app/controllers/competitions/competitions_controller.rb @@ -22,7 +22,7 @@ class Competitions::CompetitionsController < Competitions::BaseController @count = competitions.count competitions = competitions.order(published_at: :desc, online_time: :desc) - @competitions = paginate(competitions.includes(sponsor_schools: :school, current_stage_section: :competition_stage)) + @competitions = paginate(competitions.includes(:competition_mode_setting, sponsor_schools: :school, current_stage_section: :competition_stage)) ids = @competitions.map(&:id) @member_count_map = TeamMember.where(competition_id: ids).group(:competition_id).count diff --git a/app/views/competitions/competitions/index.json.jbuilder b/app/views/competitions/competitions/index.json.jbuilder index c01f0aa59..5027cdee0 100644 --- a/app/views/competitions/competitions/index.json.jbuilder +++ b/app/views/competitions/competitions/index.json.jbuilder @@ -5,7 +5,8 @@ json.competitions do json.competition_status competition.competition_status json.visits_count competition.visits - member_count = @member_count_map&.fetch(competition.id, 0) || competition.team_members.count + course = competition.competition_mode_setting.course if competition.mode == 2 + member_count = course ? course.students.count : (@member_count_map&.fetch(competition.id, 0) || competition.team_members.count) json.member_count member_count.zero? ? 268 : member_count json.image url_to_avatar(competition) From 10d3b3f5c124b85ec05ad58d8fb02c49acbb3b42 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Thu, 31 Oct 2019 16:47:43 +0800 Subject: [PATCH 05/17] =?UTF-8?q?=E7=AB=9E=E8=B5=9B=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/competition.rb | 6 ++++++ .../competitions/competitions/common_header.json.jbuilder | 2 +- app/views/competitions/competitions/index.json.jbuilder | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/models/competition.rb b/app/models/competition.rb index 9eac28616..cd26088dd 100644 --- a/app/models/competition.rb +++ b/app/models/competition.rb @@ -46,6 +46,12 @@ class Competition < ApplicationRecord end end + # 报名数 + def team_member_count + course = competition_mode_setting&.course if mode == 2 + course ? course.students.count : team_members.count + end + def sponsor_schools_name sponsor_schools.map{|sponsor| sponsor.school.name} end diff --git a/app/views/competitions/competitions/common_header.json.jbuilder b/app/views/competitions/competitions/common_header.json.jbuilder index a869d920b..0d0f3f4ca 100644 --- a/app/views/competitions/competitions/common_header.json.jbuilder +++ b/app/views/competitions/competitions/common_header.json.jbuilder @@ -1,6 +1,6 @@ json.extract! @competition, :id, :name, :sub_title, :identifier, :bonus, :mode json.visits_count @competition.visits -member_count = @competition.team_members.count +member_count = @competition.team_member_count json.member_count member_count.zero? ? 268 : member_count json.start_time @competition.start_time&.strftime("%Y-%m-%d") diff --git a/app/views/competitions/competitions/index.json.jbuilder b/app/views/competitions/competitions/index.json.jbuilder index 5027cdee0..b7a3f20e0 100644 --- a/app/views/competitions/competitions/index.json.jbuilder +++ b/app/views/competitions/competitions/index.json.jbuilder @@ -5,7 +5,7 @@ json.competitions do json.competition_status competition.competition_status json.visits_count competition.visits - course = competition.competition_mode_setting.course if competition.mode == 2 + course = competition.competition_mode_setting&.course if competition.mode == 2 member_count = course ? course.students.count : (@member_count_map&.fetch(competition.id, 0) || competition.team_members.count) json.member_count member_count.zero? ? 268 : member_count From 5ec53d0961cb6cb09969b4dcc32ab58f1c34087a Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Thu, 31 Oct 2019 18:11:45 +0800 Subject: [PATCH 06/17] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/homework_commons_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/homework_commons_controller.rb b/app/controllers/homework_commons_controller.rb index 5d27de7b8..2bb8ec6cf 100644 --- a/app/controllers/homework_commons_controller.rb +++ b/app/controllers/homework_commons_controller.rb @@ -125,7 +125,7 @@ class HomeworkCommonsController < ApplicationController # 学生已提交作品且补交(提交)已截止、作品公开、非匿评阶段 if @work&.work_status.to_i > 0 && (@homework.work_public || @homework.score_open) && ((!@homework.anonymous_comment && @homework.end_or_late) || (@homework_detail_manual.comment_status > 4 && @homework.end_or_late)) - @student_works = student_works.where("user_id != #{@work.user_id}") + @student_works = student_works.where("student_works.user_id != #{@work.user_id}") # 匿评、申诉阶段只能看到分配给自己的匿评作品 elsif @work&.work_status.to_i > 0 && @homework.anonymous_comment && @homework_detail_manual.comment_status > 2 && @homework_detail_manual.comment_status <= 4 From 2dc4664a2c1e1f6bbc69258b12941191eaaea184 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Thu, 31 Oct 2019 19:22:24 +0800 Subject: [PATCH 07/17] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../courses/shixunHomework/Listofworksstudentone.js | 2 +- .../courses/shixunHomework/Trainingjobsetting.js | 6 ++++-- .../react/src/modules/courses/shixunHomework/style.css | 10 ++++++++++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/public/react/src/modules/courses/shixunHomework/Listofworksstudentone.js b/public/react/src/modules/courses/shixunHomework/Listofworksstudentone.js index f31b1a7e8..f6f8077d4 100644 --- a/public/react/src/modules/courses/shixunHomework/Listofworksstudentone.js +++ b/public/react/src/modules/courses/shixunHomework/Listofworksstudentone.js @@ -3171,7 +3171,7 @@ class Listofworksstudentone extends Component { } daochuzuoye = () => { - let url = `/homework_commons/${this.props.match.params.homeworkid}/works_list.xlsx?group_id=${this.state.checkedValuesineinfo === undefined || this.state.checkedValuesineinfo === null ? "" : this.state.checkedValuesineinfo}&search=${this.state.searchtext === undefined || this.state.searchtext === null ? "" : this.state.searchtext}` + let url = `/homework_commons/${this.props.match.params.homeworkid}/works_list.xlsx?course_group=${this.state.checkedValuesineinfo === undefined || this.state.checkedValuesineinfo === null ? "" : this.state.checkedValuesineinfo}&search=${this.state.searchtext === undefined || this.state.searchtext === null ? "" : this.state.searchtext}` this.confirmysl(url); } diff --git a/public/react/src/modules/courses/shixunHomework/Trainingjobsetting.js b/public/react/src/modules/courses/shixunHomework/Trainingjobsetting.js index fa16e3455..88464ce1a 100644 --- a/public/react/src/modules/courses/shixunHomework/Trainingjobsetting.js +++ b/public/react/src/modules/courses/shixunHomework/Trainingjobsetting.js @@ -636,6 +636,7 @@ class Trainingjobsetting extends Component { borredszfls:this.state.borredszfls, borredszfl:this.state.borredszfl, }) + this.scrollToAnchor("zongfentimeid"); return; } var latedeductiontwos = 0; @@ -2595,6 +2596,7 @@ class Trainingjobsetting extends Component { this.Totalscorecalculation(e)} value={this.state.CalculateMax} @@ -2722,12 +2724,12 @@ class Trainingjobsetting extends Component { {this.state.challenge_settings === undefined ? "" : this.state.challenge_settings.map((object, index) => { return (
  • - this.onChangedatasheet(value, index)} - >{object.challenge_name} + >{object.challenge_name} { object.checked === false ?
    diff --git a/public/react/src/modules/courses/shixunHomework/style.css b/public/react/src/modules/courses/shixunHomework/style.css index c349fe166..6a56f7c8c 100644 --- a/public/react/src/modules/courses/shixunHomework/style.css +++ b/public/react/src/modules/courses/shixunHomework/style.css @@ -109,3 +109,13 @@ height: 20px; min-height: 20px; } + +.maxnamewidth200 { + max-width: 200px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + cursor: default; + width: 200px; + max-width: 200px; +} From f5fe4854007a35782378241211a3a3fd751d1a20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=9E=97?= <904079904@qq.com> Date: Thu, 31 Oct 2019 19:42:53 +0800 Subject: [PATCH 08/17] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../courses/shixunHomework/Trainingjobsetting.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/public/react/src/modules/courses/shixunHomework/Trainingjobsetting.js b/public/react/src/modules/courses/shixunHomework/Trainingjobsetting.js index 88464ce1a..bfbccd0e4 100644 --- a/public/react/src/modules/courses/shixunHomework/Trainingjobsetting.js +++ b/public/react/src/modules/courses/shixunHomework/Trainingjobsetting.js @@ -652,7 +652,7 @@ class Trainingjobsetting extends Component { // console.log(len); } - var max = latedeductiontwos + len; + let max = latedeductiontwos + len; // if (max > 100) { // console.log("max>100"); // this.props.showNotification(`总分值+效率效率分之和要等于100,现在分值为` + max); @@ -663,6 +663,20 @@ class Trainingjobsetting extends Component { // this.props.showNotification(`总分值+效率效率分之和要等于100,现在分值为` + max); // return; // } + if (this.state.proportion === "自定义分值") { + try { + if(parseFloat(this.state.CalculateMax)!==parseFloat(max)){ + this.props.showNotification(`总分值不等于效率分和关卡分之和!`); + this.scrollToAnchor("zongfentimeid"); + return; + } + }catch (e) { + + } + + } + + } var url = `/homework_commons/${homeworkid}/update_settings.json`; From 223e65e8f5d2548c26e2eade2dd9239982ceef7e Mon Sep 17 00:00:00 2001 From: p31729568 Date: Fri, 1 Nov 2019 08:41:05 +0800 Subject: [PATCH 09/17] get user info add email --- app/views/users/get_user_info.json.jbuilder | 1 + 1 file changed, 1 insertion(+) diff --git a/app/views/users/get_user_info.json.jbuilder b/app/views/users/get_user_info.json.jbuilder index 06794b31e..94f3f76a9 100644 --- a/app/views/users/get_user_info.json.jbuilder +++ b/app/views/users/get_user_info.json.jbuilder @@ -10,6 +10,7 @@ json.user_identity @user.identity json.tidding_count 0 json.user_phone_binded @user.phone.present? json.phone @user.phone +json.email @user.mail json.profile_completed @user.profile_completed? json.professional_certification @user.professional_certification if @course From acd8a0584ffa24b81373a6ea6f19359e04631888 Mon Sep 17 00:00:00 2001 From: p31729568 Date: Fri, 1 Nov 2019 08:45:32 +0800 Subject: [PATCH 10/17] admins: competition prize && competition prize api --- .../admins/competition_settings/index.js | 61 + .../admin-save-competition-prize-modal.js | 46 + app/assets/javascripts/common.js | 24 +- .../competition_prize_users_controller.rb | 41 + .../admins/competition_prizes_controller.rb | 43 + .../competitions/certificates_controller.rb | 23 + .../competition_modules_controller.rb | 5 + .../prize_leader_accounts_controller.rb | 25 + .../competitions/prizes_controller.rb | 26 + .../save_prize_team_account_form.rb | 9 + .../admins/competition_prize_users_helper.rb | 10 + app/models/competition.rb | 10 +- app/models/competition_prize.rb | 21 + app/models/competition_prize_user.rb | 48 + app/models/competition_team.rb | 22 + app/models/user.rb | 4 + .../admins/competition_prize_user_query.rb | 77 + .../approve_competition_prize_user_service.rb | 26 + .../create_competition_prize_users_service.rb | 70 + ...napprove_competition_prize_user_service.rb | 27 + .../save_prize_team_account_service.rb | 19 + .../competition_prize_users/approve.js.erb | 1 + .../competition_prize_users/index.html.erb | 58 + .../competition_prize_users/index.js.erb | 1 + .../shared/_list.html.erb | 33 + .../shared/_tr.html.erb | 26 + .../competition_prize_users/unapprove.js.erb | 1 + .../admins/competition_prizes/edit.js.erb | 2 + .../admins/competition_prizes/index.js.erb | 1 + .../admins/competition_prizes/new.js.erb | 2 + .../_save_competition_prize_modal.html.erb | 29 + .../competition_settings/index.html.erb | 45 +- .../shared/_competition_prizes.html.erb | 27 + app/views/admins/enroll_lists/index.html.erb | 2 +- app/views/admins/subjects/index.html.erb | 4 +- .../admins/subjects/shared/_list.html.erb | 3 +- .../competitions/prizes/show.json.jbuilder | 55 + config/admins/sidebar.yml | 4 +- config/locales/competition_prizes/zh-CN.yml | 6 + .../save_prize_team_account_form.zh-CN.yml | 8 + config/routes.rb | 16 + ...nit_competition_certificate_module_data.rb | 10 + ...0191030013802_create_competition_prizes.rb | 13 + ...30055341_create_competition_prize_users.rb | 20 + ...fest-4627fa5586ef7fed55ca286af7c028e9.json | 518 +- ...e262b3c1494e1c0fb0e00c330f0cb9d30fd7ba.js} | 2203 +- ...62b3c1494e1c0fb0e00c330f0cb9d30fd7ba.js.gz | Bin 0 -> 997013 bytes ...3fde9ccc92b404b01b37ac6064913806e3f6e.css} | 98 +- ...e9ccc92b404b01b37ac6064913806e3f6e.css.gz} | Bin 75668 -> 75873 bytes ...3cf39b8e04f2318f67bfbf1923fe208456b3.js.gz | Bin 996102 -> 0 bytes ...eb3b688aa827fa42cb8fd73d21bc96ed880236.js} | 26 +- ...3b688aa827fa42cb8fd73d21bc96ed880236.js.gz | Bin 0 -> 966944 bytes ...53ec090e49ba7ad885879ffa02a11b6efd79d74.js | 141770 --------------- ...c090e49ba7ad885879ffa02a11b6efd79d74.js.gz | Bin 966858 -> 0 bytes ...79be77d49aae9d2705ca672e78444481700d.js.gz | Bin 966852 -> 0 bytes 55 files changed, 2242 insertions(+), 143377 deletions(-) create mode 100644 app/assets/javascripts/admins/modals/admin-save-competition-prize-modal.js create mode 100644 app/controllers/admins/competition_prize_users_controller.rb create mode 100644 app/controllers/admins/competition_prizes_controller.rb create mode 100644 app/controllers/competitions/certificates_controller.rb create mode 100644 app/controllers/competitions/prize_leader_accounts_controller.rb create mode 100644 app/controllers/competitions/prizes_controller.rb create mode 100644 app/forms/competitions/save_prize_team_account_form.rb create mode 100644 app/helpers/admins/competition_prize_users_helper.rb create mode 100644 app/models/competition_prize.rb create mode 100644 app/models/competition_prize_user.rb create mode 100644 app/queries/admins/competition_prize_user_query.rb create mode 100644 app/services/admins/approve_competition_prize_user_service.rb create mode 100644 app/services/admins/create_competition_prize_users_service.rb create mode 100644 app/services/admins/unapprove_competition_prize_user_service.rb create mode 100644 app/services/competitions/save_prize_team_account_service.rb create mode 100644 app/views/admins/competition_prize_users/approve.js.erb create mode 100644 app/views/admins/competition_prize_users/index.html.erb create mode 100644 app/views/admins/competition_prize_users/index.js.erb create mode 100644 app/views/admins/competition_prize_users/shared/_list.html.erb create mode 100644 app/views/admins/competition_prize_users/shared/_tr.html.erb create mode 100644 app/views/admins/competition_prize_users/unapprove.js.erb create mode 100644 app/views/admins/competition_prizes/edit.js.erb create mode 100644 app/views/admins/competition_prizes/index.js.erb create mode 100644 app/views/admins/competition_prizes/new.js.erb create mode 100644 app/views/admins/competition_prizes/shared/_save_competition_prize_modal.html.erb create mode 100644 app/views/admins/competition_settings/shared/_competition_prizes.html.erb create mode 100644 app/views/competitions/prizes/show.json.jbuilder create mode 100644 config/locales/competition_prizes/zh-CN.yml create mode 100644 config/locales/forms/save_prize_team_account_form.zh-CN.yml create mode 100644 db/migrate/20191030005223_init_competition_certificate_module_data.rb create mode 100644 db/migrate/20191030013802_create_competition_prizes.rb create mode 100644 db/migrate/20191030055341_create_competition_prize_users.rb rename public/assets/{admin-e975e2039206e9ae2b6a072fee083cf39b8e04f2318f67bfbf1923fe208456b3.js => admin-5d791c4f4a14e1586cfa44776ae262b3c1494e1c0fb0e00c330f0cb9d30fd7ba.js} (99%) create mode 100644 public/assets/admin-5d791c4f4a14e1586cfa44776ae262b3c1494e1c0fb0e00c330f0cb9d30fd7ba.js.gz rename public/assets/{admin-6a76c25b6691b4f436608be28606d90c907ba8f033f5f47c6c20d7bf11251cb6.css => admin-70dc0e7136a8f54139e4167c00f3fde9ccc92b404b01b37ac6064913806e3f6e.css} (99%) rename public/assets/{admin-6a76c25b6691b4f436608be28606d90c907ba8f033f5f47c6c20d7bf11251cb6.css.gz => admin-70dc0e7136a8f54139e4167c00f3fde9ccc92b404b01b37ac6064913806e3f6e.css.gz} (75%) delete mode 100644 public/assets/admin-e975e2039206e9ae2b6a072fee083cf39b8e04f2318f67bfbf1923fe208456b3.js.gz rename public/assets/{cooperative-f1ac8f14ad6ade8d1f79ca49ea9c79be77d49aae9d2705ca672e78444481700d.js => cooperative-4fe879591997da39d38e94f6f5eb3b688aa827fa42cb8fd73d21bc96ed880236.js} (99%) create mode 100644 public/assets/cooperative-4fe879591997da39d38e94f6f5eb3b688aa827fa42cb8fd73d21bc96ed880236.js.gz delete mode 100644 public/assets/cooperative-a309d245cd0b0b9c653db471c53ec090e49ba7ad885879ffa02a11b6efd79d74.js delete mode 100644 public/assets/cooperative-a309d245cd0b0b9c653db471c53ec090e49ba7ad885879ffa02a11b6efd79d74.js.gz delete mode 100644 public/assets/cooperative-f1ac8f14ad6ade8d1f79ca49ea9c79be77d49aae9d2705ca672e78444481700d.js.gz diff --git a/app/assets/javascripts/admins/competition_settings/index.js b/app/assets/javascripts/admins/competition_settings/index.js index c9df31bb9..1b0dc65b0 100644 --- a/app/assets/javascripts/admins/competition_settings/index.js +++ b/app/assets/javascripts/admins/competition_settings/index.js @@ -600,6 +600,67 @@ $(document).on('turbolinks:load', function(){ $(".stage-update-form .section-start-time").datetimepicker(timeOptions); $(".stage-update-form .section-end-time").datetimepicker(timeOptions); }); + + // 奖项设置 + var $prizeContainer = $('#competition-prize-card'); + var competitionId = $prizeContainer.data('id'); + $(document).on('prize.save.success', function(){ + $.ajax({ + method: 'GET', + url: '/admins/competitions/' + competitionId + '/competition_prizes', + dataType: 'script' + }) + }); + + $('.modal.admin-upload-file-modal').on('upload:success', function(e, data){ + var $imageElement; + if(data.suffix === '_member'){ + $imageElement = $('.prize-member-image-' + data.source_id); + } else if(data.suffix === '_team'){ + $imageElement = $('.prize-team-image-' + data.source_id); + } else { + $imageElement = $('.prize-teacher-image-' + data.source_id); + } + $imageElement.attr('src', data.url); + $imageElement.show(); + $imageElement.next().html('重新上传'); + }) + + // 生成获奖记录 + $prizeContainer.on('click', '.generate-prize-user-action', function(){ + var $link = $(this); + + var generateRequest = function(){ + return $.ajax({ + method: 'POST', + url: '/admins/competitions/' + competitionId + '/competition_prize_users', + dataType: 'json', + success: function(data){ + if(data && data.status === 0){ + show_success_flash(); + $link.remove(); + } else { + showErrorNotify(data.message); + } + }, + error: function(res){ + var data = res.responseJSON; + showErrorNotify(data.message); + } + }) + } + + customConfirm({ + content: '确认生成吗?', + ok: function () { + customLoading({ + ajax: generateRequest + }) + } + }) + }); + } else { + $(document).unbind('prize.save.success'); } }); diff --git a/app/assets/javascripts/admins/modals/admin-save-competition-prize-modal.js b/app/assets/javascripts/admins/modals/admin-save-competition-prize-modal.js new file mode 100644 index 000000000..9d874dc08 --- /dev/null +++ b/app/assets/javascripts/admins/modals/admin-save-competition-prize-modal.js @@ -0,0 +1,46 @@ +$(document).on('turbolinks:load', function() { + $('.admin-modal-container').on('show.bs.modal', '.admin-save-competition-prize-modal', function(event){ + var $modal = $('.modal.admin-save-competition-prize-modal'); + var $form = $modal.find('form.admin-save-competition-prize-form'); + + $form.validate({ + errorElement: 'span', + errorClass: 'danger text-danger', + rules: { + 'competition_prize[name]': { + required: true, + maxlength: 10 + }, + 'competition_prize[num]': { + required: true, + digits: true, + min: 1 + } + } + }); + + $modal.on('click', '.submit-btn', function(){ + $form.find('.error').html(''); + var url = $form.attr('action'); + var formMethod = $form.data('form-method') + + if ($form.valid()) { + $.ajax({ + method: formMethod, + dataType: 'json', + url: url, + data: $form.serialize(), + success: function(data){ + if(data && data.status === 0) { + show_success_flash(); + $(document).trigger('prize.save.success'); + $modal.modal('hide'); + } else { + $modal.find('.error').html(data.message) + } + } + }); + } + }); + }) +}); \ No newline at end of file diff --git a/app/assets/javascripts/common.js b/app/assets/javascripts/common.js index e77b42b53..4589f52c2 100644 --- a/app/assets/javascripts/common.js +++ b/app/assets/javascripts/common.js @@ -66,10 +66,32 @@ function customConfirm(opts){ return $.confirm($.extend({}, defaultOpts, opts)) } -function show_success_flash(message) { +function customLoading(opts) { + var loading; + var defaultOpts = { + content: opts.ajax, + contentLoaded: function(){ + setTimeout(function(){ + loading.close() + }, 200); + } + } + loading = $.confirm($.extend({}, defaultOpts, opts)); + return loading; +} + +function show_success_flash(message){ $.notify({ message: message || '操作成功' },{ type: 'success' }); } + +function showErrorNotify(message){ + $.notify({ + message: message || '操作失败' + },{ + type: 'danger' + }); +} diff --git a/app/controllers/admins/competition_prize_users_controller.rb b/app/controllers/admins/competition_prize_users_controller.rb new file mode 100644 index 000000000..50d11e211 --- /dev/null +++ b/app/controllers/admins/competition_prize_users_controller.rb @@ -0,0 +1,41 @@ +class Admins::CompetitionPrizeUsersController < Admins::BaseController + def index + @competition = current_competition + + prize_users = Admins::CompetitionPrizeUserQuery.call(params.merge(competition_id: current_competition.id)) + include_class = [:competition_team, :competition_prize, :approver, + user: [:process_real_name_apply, :process_professional_apply, user_extension: :school]] + @prize_users = paginate(prize_users.preload(include_class)) + end + + def create + Admins::CreateCompetitionPrizeUsersService.call(current_competition) + render_ok + rescue ApplicationService::Error => ex + render_error(ex.message) + end + + def approve + Admins::ApproveCompetitionPrizeUserService.call(current_prize_user, current_user) + @prize_user = current_prize_user + rescue ApplicationService::Error => ex + render_js_error(ex.message, type: :notify) + end + + def unapprove + Admins::UnapproveCompetitionPrizeUserService.call(current_prize_user, current_user) + @prize_user = current_prize_user + rescue ApplicationService::Error => ex + render_js_error(ex.message, type: :notify) + end + + private + + def current_prize_user + @_current_prize_user ||= current_competition.competition_prize_users.find(params[:id]) + end + + def current_competition + @_current_competition ||= Competition.find(params[:competition_id]) + end +end \ No newline at end of file diff --git a/app/controllers/admins/competition_prizes_controller.rb b/app/controllers/admins/competition_prizes_controller.rb new file mode 100644 index 000000000..cde48f96e --- /dev/null +++ b/app/controllers/admins/competition_prizes_controller.rb @@ -0,0 +1,43 @@ +class Admins::CompetitionPrizesController < Admins::BaseController + def index + @competition = current_competition + end + + def new + @prize = current_competition.competition_prizes.new + end + + def create + @prize = current_competition.competition_prizes.create!(save_params) + render_ok + end + + def edit + @prize = current_competition_prize + end + + def update + current_competition_prize.update!(save_params) + render_ok + end + + def destroy + current_competition_prize.destroy! + + render_delete_success + end + + private + + def current_competition_prize + @_current_competition_prize ||= current_competition.competition_prizes.find(params[:id]) + end + + def current_competition + @_current_competition ||= Competition.find(params[:competition_id]) + end + + def save_params + params.require(:competition_prize).permit(:name, :category, :num) + end +end \ No newline at end of file diff --git a/app/controllers/competitions/certificates_controller.rb b/app/controllers/competitions/certificates_controller.rb new file mode 100644 index 000000000..ab52920cd --- /dev/null +++ b/app/controllers/competitions/certificates_controller.rb @@ -0,0 +1,23 @@ +class Competitions::CertificatesController < Competitions::BaseController + def personal + prize_user = CompetitionPrizeUser.find_by!(user: current_user, id: params[:id]) + return render_not_found unless prize_user.certificate_exist? + + team = prize_user.competition_team + prize = prize_user.competition_prize + filename = "#{current_competition.name}-#{prize.name}-#{team.name}-#{prize_user.user.real_name}.pdf" + + send_file prize_user.certificate_path, filename: filename + end + + def team + team = CompetitionTeam.find(id: params[:id]) + return render_forbidden unless team.team_members.exists?(user_id: current_user.id) + return render_not_found unless team.certificate_exist? + + prize = team.competition_prize_users.first.competition_prize + filename = "#{current_competition.name}-#{prize.name}-#{team.name}.pdf" + + send_file team.certificate_path, filename: filename + end +end \ No newline at end of file diff --git a/app/controllers/competitions/competition_modules_controller.rb b/app/controllers/competitions/competition_modules_controller.rb index c4692af70..8c66368fb 100644 --- a/app/controllers/competitions/competition_modules_controller.rb +++ b/app/controllers/competitions/competition_modules_controller.rb @@ -5,6 +5,11 @@ class Competitions::CompetitionModulesController < Competitions::BaseController def index @modules = current_competition.unhidden_competition_modules.order(position: :asc) + + # 未登录、未获奖用户,不展示获奖证书栏目 + if !current_user.logged? || !current_competition.competition_prize_users.exists?(user: current_user) + @modules = @modules.select { |mod| mod.name != '获奖证书' } + end end def show diff --git a/app/controllers/competitions/prize_leader_accounts_controller.rb b/app/controllers/competitions/prize_leader_accounts_controller.rb new file mode 100644 index 000000000..0c01e2738 --- /dev/null +++ b/app/controllers/competitions/prize_leader_accounts_controller.rb @@ -0,0 +1,25 @@ +class Competitions::PrizeLeaderAccountsController < Competitions::BaseController + before_action :require_prize_team_leader! + + def update + Competitions::SavePrizeTeamAccountService.call(current_competition, current_user, update_params) + render_ok + rescue ApplicationService::Error => ex + render_error(ex.message) + end + + private + + def require_prize_team_leader! + prize_user = current_competition.competition_prize_users.joins(:competition_prize) + .where(competition_prizes: { category: :bonus }) + .find_by(leader: true, user_id: current_user.id) + return if prize_user.present? + + render_forbidden + end + + def update_params + params.permit(:bank, :second_bank, :card_no) + end +end \ No newline at end of file diff --git a/app/controllers/competitions/prizes_controller.rb b/app/controllers/competitions/prizes_controller.rb new file mode 100644 index 000000000..aab1df9a1 --- /dev/null +++ b/app/controllers/competitions/prizes_controller.rb @@ -0,0 +1,26 @@ +class Competitions::PrizesController < Competitions::BaseController + before_action :require_prize_user! + + def show + self_prizes = current_competition.competition_prize_users.where(user_id: current_user.id).includes(:competition_team) + + @leader = self_prizes.any?(&:leader?) # 是否为队长 + @bank_account = self_prizes.find(&:leader?).extra if @leader + + @self_prizes = self_prizes.select(&:certificate_exist?) # 个人证书quit + @team_prizes = self_prizes.map(&:competition_team).uniq.select(&:certificate_exists?) # 团队证书 + + prize_users = current_competition.competition_prize_users.where(competition_team_id: self_prizes.map(&:competition_team_id)) + .includes(:competition_team, user: [:user_extension, :process_real_name_apply, :process_professional_apply]) + + @prize_user_map = prize_users.group_by(&:competition_team) + end + + private + + def require_prize_user! + return if current_competition.competition_prize_users.exists?(user: current_user) + + render_forbidden + end +end \ No newline at end of file diff --git a/app/forms/competitions/save_prize_team_account_form.rb b/app/forms/competitions/save_prize_team_account_form.rb new file mode 100644 index 000000000..b048c8368 --- /dev/null +++ b/app/forms/competitions/save_prize_team_account_form.rb @@ -0,0 +1,9 @@ +class Competitions::SavePrizeTeamAccountForm + include ActiveModel::Model + + attr_accessor :bank, :second_bank, :card_no + + validates :bank, presence: true + validates :second_bank, presence: true + validates :card_no, presence: true +end diff --git a/app/helpers/admins/competition_prize_users_helper.rb b/app/helpers/admins/competition_prize_users_helper.rb new file mode 100644 index 000000000..0fa338341 --- /dev/null +++ b/app/helpers/admins/competition_prize_users_helper.rb @@ -0,0 +1,10 @@ +module Admins::CompetitionPrizeUsersHelper + def display_auth_state(flag, other = false, success: nil, normal: nil, error: nil) + success ||= ''.html_safe + normal ||= '--' + error ||= ''.html_safe + + return success if flag + other ? normal : error + end +end \ No newline at end of file diff --git a/app/models/competition.rb b/app/models/competition.rb index 9eac28616..8613e974a 100644 --- a/app/models/competition.rb +++ b/app/models/competition.rb @@ -29,6 +29,9 @@ class Competition < ApplicationRecord has_many :competition_managers, dependent: :destroy has_many :managers, through: :competition_managers, source: :user + has_many :competition_prizes, dependent: :destroy + has_many :competition_prize_users, dependent: :destroy + after_create :create_competition_modules def mode_type @@ -131,7 +134,7 @@ class Competition < ApplicationRecord end def all_module_types - %w[home enroll inform chart resource] + %w[home enroll inform chart resource certificate] end def max_stage_end_time @@ -146,6 +149,10 @@ class Competition < ApplicationRecord user && competition_managers.exists?(user_id: user.id) end + def finished? + end_time.blank? || end_time < Time.now + end + private def get_module_name type @@ -155,6 +162,7 @@ class Competition < ApplicationRecord when 'inform' then '通知公告' when 'chart' then '排行榜' when 'resource' then '资料下载' + when 'certificate' then '获奖证书' else '' end end diff --git a/app/models/competition_prize.rb b/app/models/competition_prize.rb new file mode 100644 index 000000000..8acbc6713 --- /dev/null +++ b/app/models/competition_prize.rb @@ -0,0 +1,21 @@ +class CompetitionPrize < ApplicationRecord + extend Enumerize + + belongs_to :competition + + has_many :competition_prize_users, dependent: :destroy + + enumerize :category, in: %i[bonus unset] + + def self.member_suffix + '_member' + end + + def self.teacher_suffix + '_teacher' + end + + def self.team_suffix + '_team' + end +end \ No newline at end of file diff --git a/app/models/competition_prize_user.rb b/app/models/competition_prize_user.rb new file mode 100644 index 000000000..fe5877e4d --- /dev/null +++ b/app/models/competition_prize_user.rb @@ -0,0 +1,48 @@ +class CompetitionPrizeUser < ApplicationRecord + include AASM + + belongs_to :competition + belongs_to :competition_team + belongs_to :competition_prize + belongs_to :user + belongs_to :approver, class_name: 'User', optional: true # 审批人 + + serialize :extra, JSON + + aasm(:status) do + state :pending, initial: true + state :approved + + event :approve do + transitions from: [:pending], to: :approved, guard: :user_certified? + end + + event :unapprove do + transitions from: [:approved], to: :pending + end + end + + delegate :bank, :second_bank, :card_no, to: :extra, allow_nil: true + + def user_certified? + user.certification? && user.professional_certification? + end + + def certificate_exist? + Util::FileManage.exists?(self) + end + + def certificate_url + Util::FileManage.source_disk_file_url(self) + end + + def certificate_path + Util::FileManage.source_disk_filename(self) + end + + def role_text + return '队长' if leader? + + user.is_teacher? ? '教师' : '队员' + end +end \ No newline at end of file diff --git a/app/models/competition_team.rb b/app/models/competition_team.rb index a05ceb032..ecfdd218a 100644 --- a/app/models/competition_team.rb +++ b/app/models/competition_team.rb @@ -11,6 +11,8 @@ class CompetitionTeam < ApplicationRecord has_many :members, -> { without_teachers }, class_name: 'TeamMember' has_many :teachers, -> { only_teachers }, class_name: 'TeamMember' + has_many :competition_prize_users, dependent: :destroy + def group_team_type? team_type.zero? end @@ -48,4 +50,24 @@ class CompetitionTeam < ApplicationRecord def members_name members.map{|member| member.user.real_name}.join(",") end + + def all_prize_approved? + !competition_prize_users.exists?(status: :pending) + end + + def certificate_exists? + Util::FileManage.exists?(self, self.class.certificate_suffix) + end + + def certificate_url + Util::FileManage.source_disk_file_url(self, self.class.certificate_suffix) + end + + def certificate_path + Util::FileManage.source_disk_filename(self, self.class.certificate_suffix) + end + + def self.certificate_suffix + '_CERT' + end end \ No newline at end of file diff --git a/app/models/user.rb b/app/models/user.rb index 4d13727db..85b9ef551 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -503,6 +503,10 @@ class User < ApplicationRecord phone.present? end + def email_binded? + mail.present? + end + def self.current=(user) Thread.current[:current_user] = user end diff --git a/app/queries/admins/competition_prize_user_query.rb b/app/queries/admins/competition_prize_user_query.rb new file mode 100644 index 000000000..c6cdfb562 --- /dev/null +++ b/app/queries/admins/competition_prize_user_query.rb @@ -0,0 +1,77 @@ +class Admins::CompetitionPrizeUserQuery < ApplicationQuery + include CustomSortable + + attr_reader :params + + sort_columns :rank, default_by: :rank, default_direction: :asc + + def initialize(params) + @params = params + end + + def call + records = CompetitionPrizeUser.all + + # 竞赛过滤 + records = records.where(competition_id: params[:competition_id]) if params[:competition_id].present? + + # 关键字检索 + keyword = params[:keyword].to_s.strip + if keyword.present? + like_sql = 'competition_teams.name LIKE :keyword OR schools.name LIKE :keyword' + records = records.left_joins(:competition_team, user: { user_extension: :school }) + .where(like_sql, keyword: "%#{keyword}%") + end + + # 奖项过滤 + records = records.where(competition_prize_id: params[:prize_id]) if params[:prize_id].present? + + # 审批状态过滤 + records = records.where(status: params[:status]) if params[:status].present? + + # 职业过滤 + if params[:identity].present? + records = records.left_joins(user: :user_extension).where(user_extensions: { identity: params[:identity] }) + end + + # 实名认证过滤 + records = real_name_auth_filter(records) if params[:real_name_auth].present? + + # 职业认证过滤 + records = professional_auth_filter(records) if params[:professional_auth].present? + + custom_sort(records, params[:sort_by], params[:sort_direction]) + end + + private + + def real_name_auth_filter(records) + records = records.left_joins(:user) + sql = ApplyUserAuthentication.real_name_auth.processing.where('apply_user_authentications.user_id = users.id').to_sql + + case params[:real_name_auth] + when 'authed' then + records.where(users: { authentication: true }) + when 'not_authed' then + records.where(users: { authentication: false }).where("NOT EXISTS (#{sql})") + when 'authing' then + records.where(users: { authentication: false }).where("EXISTS (#{sql})") + else records + end + end + + def professional_auth_filter(records) + records = records.left_joins(:user) + sql = ApplyUserAuthentication.professional_auth.processing.where('apply_user_authentications.user_id = users.id').to_sql + + case params[:professional_auth] + when 'authed' then + records.where(users: { professional_certification: true }) + when 'not_authed' then + records.where(users: { professional_certification: false }).where("NOT EXISTS (#{sql})") + when 'authing' then + records.where(users: { professional_certification: false }).where("EXISTS (#{sql})") + else records + end + end +end \ No newline at end of file diff --git a/app/services/admins/approve_competition_prize_user_service.rb b/app/services/admins/approve_competition_prize_user_service.rb new file mode 100644 index 000000000..cd1c2101b --- /dev/null +++ b/app/services/admins/approve_competition_prize_user_service.rb @@ -0,0 +1,26 @@ +class Admins::ApproveCompetitionPrizeUserService < ApplicationService + attr_reader :prize_user, :approver + + def initialize(prize_user, approver) + @prize_user = prize_user + @approver = approver + end + + def call + raise Error, '请勿重复审批' if prize_user.approved? + raise Error, '该用户未认证完成' unless prize_user.user_certified? + + ActiveRecord::Base.transaction do + prize_user.approve + prize_user.approver = approver + prize_user.approved_at = Time.now + prize_user.save! + + if prize_user.competition_team.all_prize_approved? + # TODO: 生成团队证书 + end + + # TODO: 生成个人证书 + end + end +end \ No newline at end of file diff --git a/app/services/admins/create_competition_prize_users_service.rb b/app/services/admins/create_competition_prize_users_service.rb new file mode 100644 index 000000000..0cacaa2f1 --- /dev/null +++ b/app/services/admins/create_competition_prize_users_service.rb @@ -0,0 +1,70 @@ +class Admins::CreateCompetitionPrizeUsersService < ApplicationService + attr_reader :competition + + def initialize(competition) + @competition = competition + end + + def call + raise Error, '竞赛还未结束' unless competition.finished? + raise Error, '请勿重复生成' if competition.competition_prize_users.exists? + raise Error, '请先设置奖项' if prizes.blank? + raise Error, '无获奖队伍' if prize_teams.blank? + + ActiveRecord::Base.transaction do + columns = %i[competition_id competition_team_id competition_prize_id user_id + status rank leader created_at updated_at] + + CompetitionPrizeUser.bulk_insert(*columns) do |worker| + prize_teams.each_with_index do |team, index| + rank = index + 1 + prize = team_prize(rank) # 根据排名获取当前队伍奖项 + + team.team_members.each do |member| + attr = { + competition_id: competition.id, + competition_team_id: team.id, + competition_prize_id: prize.id, + user_id: member.user_id, + leader: member.creator?, + status: :pending, + rank: rank + } + + worker.add(attr) + end + end + end + end + end + + private + + def prizes + @_prizes ||= competition.competition_prizes.order(id: :asc).to_a + end + + def team_prize(rank) + current = 0 + prizes.each do |prize| + return prize if rank > current && rank <= current + prize.num + + current += prize.num + end + end + + def prize_teams + @_prize_teams ||= begin + prize_num_total = prizes.sum(&:num) + + # 只有一个阶段,则成绩为该阶段成绩,否则为stage ID为0的总成绩 + stage_id = competition.competition_stages.count == 1 ? competition.competition_stages.first.id : 0 + + competition.competition_teams.joins(:competition_scores) + .where(competition_scores: { competition_stage_id: stage_id }) + .order("competition_scores.score desc, competition_scores.cost_time desc") + .includes(:team_members) + .limit(prize_num_total) + end + end +end \ No newline at end of file diff --git a/app/services/admins/unapprove_competition_prize_user_service.rb b/app/services/admins/unapprove_competition_prize_user_service.rb new file mode 100644 index 000000000..0bfcd20c1 --- /dev/null +++ b/app/services/admins/unapprove_competition_prize_user_service.rb @@ -0,0 +1,27 @@ +class Admins::UnapproveCompetitionPrizeUserService < ApplicationService + attr_reader :prize_user, :approver + + def initialize(prize_user, approver) + @prize_user = prize_user + @approver = approver + end + + def call + raise Error, '状态有误' if prize_user.pending? + + ActiveRecord::Base.transaction do + prize_user.unapprove + prize_user.approver = approver + prize_user.approved_at = nil + prize_user.save! + + # 删除团队证书 + team_certificate_path = Util::FileManage.source_disk_filename(prize_user.competition_team, CompetitionTeam.certificate_suffix) + File.delete(team_certificate_path) if File.exist?(team_certificate_path) + + # 删除个人证书 + user_certificate_path = Util::FileManage.source_disk_filename(prize_user) + File.delete(user_certificate_path) if File.exist?(user_certificate_path) + end + end +end \ No newline at end of file diff --git a/app/services/competitions/save_prize_team_account_service.rb b/app/services/competitions/save_prize_team_account_service.rb new file mode 100644 index 000000000..60d10cf54 --- /dev/null +++ b/app/services/competitions/save_prize_team_account_service.rb @@ -0,0 +1,19 @@ +class Competitions::SavePrizeTeamAccountService < ApplicationService + attr_reader :competition, :user, :params + + def initialize(competition, user, params) + @competition = competition + @user = user + @params = params + end + + def call + Competitions::SavePrizeTeamAccountForm.new(params).validate! + + prize_leaders = competition.competition_prize_users.where(competition.competition_prize_users) + + raise Error, '审批通过后不能修改' if prize_leaders.exists?(status: :approved) + + prize_leaders.update_all(extra: params) + end +end \ No newline at end of file diff --git a/app/views/admins/competition_prize_users/approve.js.erb b/app/views/admins/competition_prize_users/approve.js.erb new file mode 100644 index 000000000..d8e8f3a66 --- /dev/null +++ b/app/views/admins/competition_prize_users/approve.js.erb @@ -0,0 +1 @@ +$('.competition-prize-user-list-container .competition-prize-user-item-<%= @prize_user.id %>').html("<%= j( render partial: 'admins/competition_prize_users/shared/tr', locals: { prize_user: @prize_user } ) %>"); \ No newline at end of file diff --git a/app/views/admins/competition_prize_users/index.html.erb b/app/views/admins/competition_prize_users/index.html.erb new file mode 100644 index 000000000..dbb86d066 --- /dev/null +++ b/app/views/admins/competition_prize_users/index.html.erb @@ -0,0 +1,58 @@ +<% + define_admin_breadcrumbs do + add_admin_breadcrumb('竞赛列表', admins_competitions_path) + add_admin_breadcrumb(@competition.name) + end +%> + +
    + + +
    + <%= form_tag(admins_competition_competition_prize_users_path(unsafe_params), method: :get, class: 'search-form mt-3 flex-1 d-flex align-items-end', remote: true) do %> +
    + + <% prize_options = [['不限', '']] + @competition.competition_prizes.map{ |p| [p.name, p.id] } %> + <%= select_tag(:prize_id, options_for_select(prize_options), class: 'form-control') %> +
    + + <% auth_options = [['不限', ''], %w(未认证 not_authed), %w(待认证 authing), %w(已认证 authed)] %> +
    + + <%= select_tag(:real_name_auth, options_for_select(auth_options), class: 'form-control') %> +
    +
    + + <%= select_tag(:professional_auth, options_for_select(auth_options), class: 'form-control') %> +
    + +
    + + <%- identity_options = [['不限', ''], %w(教师 0), %w(学生 1)] %> + <%= select_tag(:identity, options_for_select(identity_options), class: 'form-control') %> +
    + +
    + + <%- status_options = [['不限', ''], %w(未审批 pending), %w(已审批 approved)] %> + <%= select_tag(:status, options_for_select(status_options), class: 'form-control') %> +
    + + <%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: '战队/学校名称检索') %> + + <%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %> + <%= link_to '清除', admins_competition_competition_prize_users_path(@competition), class: "btn btn-default",'data-disable-with': '清除中...' %> + <% end %> +
    +
    + +
    + <%= render(partial: 'admins/competition_prize_users/shared/list', locals: { prize_users: @prize_users }) %> +
    \ No newline at end of file diff --git a/app/views/admins/competition_prize_users/index.js.erb b/app/views/admins/competition_prize_users/index.js.erb new file mode 100644 index 000000000..53091f7d5 --- /dev/null +++ b/app/views/admins/competition_prize_users/index.js.erb @@ -0,0 +1 @@ +$('.competition-prize-user-list-container').html("<%= j( render partial: 'admins/competition_prize_users/shared/list', locals: { prize_users: @prize_users } ) %>"); \ No newline at end of file diff --git a/app/views/admins/competition_prize_users/shared/_list.html.erb b/app/views/admins/competition_prize_users/shared/_list.html.erb new file mode 100644 index 000000000..27cb5b46c --- /dev/null +++ b/app/views/admins/competition_prize_users/shared/_list.html.erb @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + <% if prize_users.present? %> + <% prize_users.each do |prize_user| %> + + <%= render('admins/competition_prize_users/shared/tr', prize_user: prize_user) %> + + <% end %> + <% else %> + <%= render 'admins/shared/no_data_for_table' %> + <% end %> + +
    奖项排名战队名称真实姓名职业学号单位实名职业手机队长审批时间审批人操作
    + +<%= render partial: 'admins/shared/paginate', locals: { objects: prize_users } %> \ No newline at end of file diff --git a/app/views/admins/competition_prize_users/shared/_tr.html.erb b/app/views/admins/competition_prize_users/shared/_tr.html.erb new file mode 100644 index 000000000..d3b2cd51d --- /dev/null +++ b/app/views/admins/competition_prize_users/shared/_tr.html.erb @@ -0,0 +1,26 @@ +<%- user = prize_user.user -%> +<%= prize_user.competition_prize.name %> +<%= prize_user.rank %> +<%= prize_user.competition_team.name %> +<%= user.real_name %> +<%= user.identity %> +<%= user.is_teacher? ? user.user_extension.technical_title : user.user_extension.student_id %> +<%= user.school_name %> +<%= display_auth_state(user.authentication?, user.process_real_name_apply.present?) %> +<%= display_auth_state(user.professional_certification?, user.process_professional_apply.present?) %> +<%= display_auth_state user.phone_binded? %> +<%= display_auth_state prize_user.leader?, error: '' %> +<%= display_text prize_user.approved_at&.strftime('%Y-%m-%d %H:%M') %> +<%= display_text prize_user.approver&.real_name %> + + + <% if prize_user.pending? %> + <%= link_to('审批通过', approve_admins_competition_competition_prize_user_path(prize_user.competition, prize_user), + data: { confirm: '确认审批通过吗?' }, + remote: true, method: :post, class: 'approve-action') %> + <% else %> + <%= link_to('撤销审批', unapprove_admins_competition_competition_prize_user_path(prize_user.competition, prize_user), + data: { confirm: '确认撤销审批吗?' }, + remote: true, method: :post, class: 'approve-action') %> + <% end %> + \ No newline at end of file diff --git a/app/views/admins/competition_prize_users/unapprove.js.erb b/app/views/admins/competition_prize_users/unapprove.js.erb new file mode 100644 index 000000000..d8e8f3a66 --- /dev/null +++ b/app/views/admins/competition_prize_users/unapprove.js.erb @@ -0,0 +1 @@ +$('.competition-prize-user-list-container .competition-prize-user-item-<%= @prize_user.id %>').html("<%= j( render partial: 'admins/competition_prize_users/shared/tr', locals: { prize_user: @prize_user } ) %>"); \ No newline at end of file diff --git a/app/views/admins/competition_prizes/edit.js.erb b/app/views/admins/competition_prizes/edit.js.erb new file mode 100644 index 000000000..7e3eb89c6 --- /dev/null +++ b/app/views/admins/competition_prizes/edit.js.erb @@ -0,0 +1,2 @@ +$('.admin-modal-container').html("<%= j( render partial: 'admins/competition_prizes/shared/save_competition_prize_modal', locals: { prize: @prize, title: '编辑奖项', form_method: 'PATCH' } ) %>"); +$('.modal.admin-save-competition-prize-modal').modal('show'); \ No newline at end of file diff --git a/app/views/admins/competition_prizes/index.js.erb b/app/views/admins/competition_prizes/index.js.erb new file mode 100644 index 000000000..6b9a49cfe --- /dev/null +++ b/app/views/admins/competition_prizes/index.js.erb @@ -0,0 +1 @@ +$('#competition-prize-card .competition-prize-table tbody').html("<%= j( render partial: 'admins/competition_settings/shared/competition_prizes', locals: { competition: @competition } ) %>"); \ No newline at end of file diff --git a/app/views/admins/competition_prizes/new.js.erb b/app/views/admins/competition_prizes/new.js.erb new file mode 100644 index 000000000..8e19df25d --- /dev/null +++ b/app/views/admins/competition_prizes/new.js.erb @@ -0,0 +1,2 @@ +$('.admin-modal-container').html("<%= j( render partial: 'admins/competition_prizes/shared/save_competition_prize_modal', locals: { prize: @prize, title: '新建奖项', form_method: 'POST' } ) %>"); +$('.modal.admin-save-competition-prize-modal').modal('show'); \ No newline at end of file diff --git a/app/views/admins/competition_prizes/shared/_save_competition_prize_modal.html.erb b/app/views/admins/competition_prizes/shared/_save_competition_prize_modal.html.erb new file mode 100644 index 000000000..5bdc8fa0e --- /dev/null +++ b/app/views/admins/competition_prizes/shared/_save_competition_prize_modal.html.erb @@ -0,0 +1,29 @@ + \ No newline at end of file diff --git a/app/views/admins/competition_settings/index.html.erb b/app/views/admins/competition_settings/index.html.erb index 1c60f0601..9d929f024 100644 --- a/app/views/admins/competition_settings/index.html.erb +++ b/app/views/admins/competition_settings/index.html.erb @@ -266,7 +266,7 @@ <% end %>
    - <% when 'inform', 'chart', 'resource' %> + <% when 'inform', 'chart', 'resource', 'certificate' %>
    + +
    +
    + 奖项配置 + + <%= link_to '新增奖项', new_admins_competition_competition_prize_path(@competition), remote: true, class: 'btn btn-primary btn-sm add-competition-prize-btn' %> + + <% if @competition.finished? && !@competition.competition_prize_users.exists? %> + <%= javascript_void_link '生成获奖记录', class: 'btn btn-primary btn-sm ml-2 generate-prize-user-action' %> + <% end %> +
    +
    + + + + + + + + + + + + + <%= render 'admins/competition_settings/shared/competition_prizes', competition: @competition %> + +
    序号奖项名称数量奖励类型队员个人证书模板团队证书模板指导老师证书模板操作
    +
    +
    -<%# end %> \ No newline at end of file +<%# end %> + +<%= render partial: 'admins/shared/modal/upload_file_modal', locals: { title: '上传证书模板', accept: 'image/*' } %> \ No newline at end of file diff --git a/app/views/admins/competition_settings/shared/_competition_prizes.html.erb b/app/views/admins/competition_settings/shared/_competition_prizes.html.erb new file mode 100644 index 000000000..41c4afeda --- /dev/null +++ b/app/views/admins/competition_settings/shared/_competition_prizes.html.erb @@ -0,0 +1,27 @@ +<% competition.competition_prizes.each_with_index do |prize, index| %> + + <%= index + 1 %> + <%= prize.name %> + <%= prize.num %> + <%= prize.category_text %> + + <% member_image_exists = Util::FileManage.exists?(prize, CompetitionPrize.member_suffix) %> + <%= image_tag(member_image_exists ? Util::FileManage.source_disk_file_url(prize, CompetitionPrize.member_suffix) : '', height: 60, class: "w-100 preview-image prize-member-image-#{prize.id}", style: member_image_exists ? '' : 'display:none') %> + <%= javascript_void_link member_image_exists ? '重新上传' : '上传模板', class: 'action upload-prize-member-image-action', data: { source_id: prize.id, source_type: 'CompetitionPrize', suffix: CompetitionPrize.member_suffix, toggle: 'modal', target: '.admin-upload-file-modal' } %> + + + <% team_image_exists = Util::FileManage.exists?(prize, CompetitionPrize.team_suffix) %> + <%= image_tag(team_image_exists ? Util::FileManage.source_disk_file_url(prize, CompetitionPrize.team_suffix) : '', height: 60, class: "w-100 preview-image prize-team-image-#{prize.id}", style: team_image_exists ? '' : 'display:none') %> + <%= javascript_void_link team_image_exists ? '重新上传' : '上传模板', class: 'action upload-prize-team-image-action', data: { source_id: prize.id, source_type: 'CompetitionPrize', suffix: CompetitionPrize.team_suffix, toggle: 'modal', target: '.admin-upload-file-modal' } %> + + + <% teacher_image_exists = Util::FileManage.exists?(prize, CompetitionPrize.teacher_suffix) %> + <%= image_tag(teacher_image_exists ? Util::FileManage.source_disk_file_url(prize, CompetitionPrize.teacher_suffix) : '', height: 60, class: "w-100 preview-image prize-teacher-image-#{prize.id}", style: teacher_image_exists ? '' : 'display:none') %> + <%= javascript_void_link teacher_image_exists ? '重新上传' : '上传模板', class: 'action upload-prize-teacher-image-action', data: { source_id: prize.id, source_type: 'CompetitionPrize', suffix: CompetitionPrize.teacher_suffix, toggle: 'modal', target: '.admin-upload-file-modal' } %> + + + <%= link_to '编辑', edit_admins_competition_competition_prize_path(competition, prize), remote: true, class: 'action edit-competition-prize-action' %> + <%= delete_link '删除', admins_competition_competition_prize_path(competition, prize, element: ".competition-prize-item-#{prize.id}"), class: 'action delete-competition-prize-action' %> + + +<% end %> \ No newline at end of file diff --git a/app/views/admins/enroll_lists/index.html.erb b/app/views/admins/enroll_lists/index.html.erb index 636479377..4476c347a 100644 --- a/app/views/admins/enroll_lists/index.html.erb +++ b/app/views/admins/enroll_lists/index.html.erb @@ -11,7 +11,7 @@ <%= link_to '报名列表', admins_competition_enroll_lists_path(@competition), class: "nav-link search-form-tab active" %>
  • diff --git a/app/views/admins/subjects/index.html.erb b/app/views/admins/subjects/index.html.erb index 9d64ed2c3..bba06b284 100644 --- a/app/views/admins/subjects/index.html.erb +++ b/app/views/admins/subjects/index.html.erb @@ -36,4 +36,6 @@
    <%= render partial: 'admins/subjects/shared/list', locals: { subjects: @subjects } %> -
    \ No newline at end of file + + +<%= render partial: 'admins/shared/modal/upload_file_modal', locals: { title: '上传图片', accept: 'image/*' } %> \ No newline at end of file diff --git a/app/views/admins/subjects/shared/_list.html.erb b/app/views/admins/subjects/shared/_list.html.erb index 24ff1aa63..431ad317a 100644 --- a/app/views/admins/subjects/shared/_list.html.erb +++ b/app/views/admins/subjects/shared/_list.html.erb @@ -69,5 +69,4 @@ -<%= render partial: 'admins/shared/paginate', locals: { objects: subjects } %> -<%= render partial: 'admins/shared/modal/upload_file_modal', locals: { title: '上传图片', accept: 'image/*' } %> \ No newline at end of file +<%= render partial: 'admins/shared/paginate', locals: { objects: subjects } %> \ No newline at end of file diff --git a/app/views/competitions/prizes/show.json.jbuilder b/app/views/competitions/prizes/show.json.jbuilder new file mode 100644 index 000000000..5bd4a5ae6 --- /dev/null +++ b/app/views/competitions/prizes/show.json.jbuilder @@ -0,0 +1,55 @@ +json.leader @leader + +json.bank_account @bank_account if @leader + +json.personal_certifications do + json.array! @self_prizes do |prize_user| + json.url personal_competitions_certificate_path(current_competition, prize_user) + end +end + +json.team_certifications do + json.array! @team_prizes do |team| + json.url team_competitions_certificate_path(current_competition, team) + end +end + +json.teams do + json.array! @prize_user_map do |team, prize_users| + json.extract! team, :id, :name + + json.bank_account prize_users.find(&:leader?).extra + + json.team_members do + json.array! prize_users do |prize_user| + user = prize_user.user + + json.role prize_user.role_text + json.name user.real_name + + real_name_auth = + if user.authentication? + 'authed' + elsif user.process_real_name_apply.present? + 'authing' + else + 'not_authed' + end + json.real_name_auth real_name_auth + + professional_auth = + if user.professional_certification? + 'authed' + elsif user.process_professional_apply.present? + 'authing' + else + 'not_authed' + end + json.professional_auth professional_auth + + json.phone_binded user.phone_binded? + json.email_binded user.email_binded? + end + end + end +end \ No newline at end of file diff --git a/config/admins/sidebar.yml b/config/admins/sidebar.yml index b722f2505..d0cb41129 100644 --- a/config/admins/sidebar.yml +++ b/config/admins/sidebar.yml @@ -1,4 +1,6 @@ admins-mirror_scripts: 'admins-mirror_repositories' admins-laboratory_settings: 'admins-laboratories' admins-carousels: 'admins-laboratories' -admins-competition_settings: 'admins-competitions' \ No newline at end of file +admins-competition_settings: 'admins-competitions' +admins-enroll_lists: 'admins-competitions' +admins-competition_prize_users: 'admins-competitions' \ No newline at end of file diff --git a/config/locales/competition_prizes/zh-CN.yml b/config/locales/competition_prizes/zh-CN.yml new file mode 100644 index 000000000..91d905e1a --- /dev/null +++ b/config/locales/competition_prizes/zh-CN.yml @@ -0,0 +1,6 @@ +zh-CN: + enumerize: + competition_prize: + category: + bonus: '奖金' + unset: '无' \ No newline at end of file diff --git a/config/locales/forms/save_prize_team_account_form.zh-CN.yml b/config/locales/forms/save_prize_team_account_form.zh-CN.yml new file mode 100644 index 000000000..3f6b52f7f --- /dev/null +++ b/config/locales/forms/save_prize_team_account_form.zh-CN.yml @@ -0,0 +1,8 @@ +'zh-CN': + activemodel: + attributes: + competitions/save_prize_team_account_form: + bank: '开户行' + second_bank: '支行' + card_no: '卡号' + diff --git a/config/routes.rb b/config/routes.rb index 2f8f3d958..523b1bd5d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -809,6 +809,14 @@ Rails.application.routes.draw do get :chart_rules post :update_chart_rules end + resource :prize_leader_account, only: [:update] + resource :prize, only: [:show] + resources :certificates, only: [] do + member do + get :personal + get :team + end + end end end @@ -1043,6 +1051,14 @@ Rails.application.routes.draw do post :calculate_stage_score end end + + resources :competition_prizes, only: [:index, :new, :create, :edit, :update, :destroy] + resources :competition_prize_users, only: [:index, :create] do + member do + post :approve + post :unapprove + end + end end resources :weapp_carousels, only: [:index, :create, :update, :destroy] do diff --git a/db/migrate/20191030005223_init_competition_certificate_module_data.rb b/db/migrate/20191030005223_init_competition_certificate_module_data.rb new file mode 100644 index 000000000..75eedbd86 --- /dev/null +++ b/db/migrate/20191030005223_init_competition_certificate_module_data.rb @@ -0,0 +1,10 @@ +class InitCompetitionCertificateModuleData < ActiveRecord::Migration[5.2] + def change + Competition.find_each do |competition| + competition.competition_modules.where(module_type: 'certificate').delete_all + + position = competition.competition_modules.maximum(:position) + 1 + competition.competition_modules.create(module_type: 'certificate', position: position, name: '获奖证书', hidden: true) + end + end +end diff --git a/db/migrate/20191030013802_create_competition_prizes.rb b/db/migrate/20191030013802_create_competition_prizes.rb new file mode 100644 index 000000000..bafacf22d --- /dev/null +++ b/db/migrate/20191030013802_create_competition_prizes.rb @@ -0,0 +1,13 @@ +class CreateCompetitionPrizes < ActiveRecord::Migration[5.2] + def change + create_table :competition_prizes do |t| + t.references :competition + + t.string :name + t.string :category + t.integer :num + + t.timestamps + end + end +end diff --git a/db/migrate/20191030055341_create_competition_prize_users.rb b/db/migrate/20191030055341_create_competition_prize_users.rb new file mode 100644 index 000000000..ab1e31144 --- /dev/null +++ b/db/migrate/20191030055341_create_competition_prize_users.rb @@ -0,0 +1,20 @@ +class CreateCompetitionPrizeUsers < ActiveRecord::Migration[5.2] + def change + create_table :competition_prize_users do |t| + t.references :competition + t.references :competition_team + t.references :competition_prize + t.references :user + t.references :approver + + t.string :status + t.integer :rank + t.boolean :leader, default: false + t.text :extra + + t.datetime :approved_at + + t.timestamps + end + end +end diff --git a/public/assets/.sprockets-manifest-4627fa5586ef7fed55ca286af7c028e9.json b/public/assets/.sprockets-manifest-4627fa5586ef7fed55ca286af7c028e9.json index 2641a3029..21ae5d0c3 100644 --- a/public/assets/.sprockets-manifest-4627fa5586ef7fed55ca286af7c028e9.json +++ b/public/assets/.sprockets-manifest-4627fa5586ef7fed55ca286af7c028e9.json @@ -1,517 +1 @@ -{ - "files": { - "admin-cd9ca8bacc973ce2dbace30c97f6c40bc08e2c2ee44972f668e738e1902c0121.js": { - "logical_path": "admin.js", - "mtime": "2019-09-11T16:20:07+08:00", - "size": 4350881, - "digest": "cd9ca8bacc973ce2dbace30c97f6c40bc08e2c2ee44972f668e738e1902c0121", - "integrity": "sha256-zZyousyXPOLbrOMMl/bEC8COLC7kSXL2aOc44ZAsASE=" - }, - "admin-a1b3356efe50ff4717cf22475639b5333c5354ba03fd107c9b7a8d4ae76f47aa.css": { - "logical_path": "admin.css", - "mtime": "2019-09-11T16:20:07+08:00", - "size": 773445, - "digest": "a1b3356efe50ff4717cf22475639b5333c5354ba03fd107c9b7a8d4ae76f47aa", - "integrity": "sha256-obM1bv5Q/0cXzyJHVjm1MzxTVLoD/RB8m3qNSudvR6o=" - }, - "font-awesome/fontawesome-webfont-7bfcab6db99d5cfbf1705ca0536ddc78585432cc5fa41bbd7ad0f009033b2979.eot": { - "logical_path": "font-awesome/fontawesome-webfont.eot", - "mtime": "2019-08-14T17:22:43+08:00", - "size": 165742, - "digest": "7bfcab6db99d5cfbf1705ca0536ddc78585432cc5fa41bbd7ad0f009033b2979", - "integrity": "sha256-e/yrbbmdXPvxcFygU23ceFhUMsxfpBu9etDwCQM7KXk=" - }, - "font-awesome/fontawesome-webfont-2adefcbc041e7d18fcf2d417879dc5a09997aa64d675b7a3c4b6ce33da13f3fe.woff2": { - "logical_path": "font-awesome/fontawesome-webfont.woff2", - "mtime": "2019-08-14T17:22:43+08:00", - "size": 77160, - "digest": "2adefcbc041e7d18fcf2d417879dc5a09997aa64d675b7a3c4b6ce33da13f3fe", - "integrity": "sha256-Kt78vAQefRj88tQXh53FoJmXqmTWdbejxLbOM9oT8/4=" - }, - "font-awesome/fontawesome-webfont-ba0c59deb5450f5cb41b3f93609ee2d0d995415877ddfa223e8a8a7533474f07.woff": { - "logical_path": "font-awesome/fontawesome-webfont.woff", - "mtime": "2019-08-14T17:22:43+08:00", - "size": 98024, - "digest": "ba0c59deb5450f5cb41b3f93609ee2d0d995415877ddfa223e8a8a7533474f07", - "integrity": "sha256-ugxZ3rVFD1y0Gz+TYJ7i0NmVQVh33foiPoqKdTNHTwc=" - }, - "font-awesome/fontawesome-webfont-aa58f33f239a0fb02f5c7a6c45c043d7a9ac9a093335806694ecd6d4edc0d6a8.ttf": { - "logical_path": "font-awesome/fontawesome-webfont.ttf", - "mtime": "2019-08-14T17:22:43+08:00", - "size": 165548, - "digest": "aa58f33f239a0fb02f5c7a6c45c043d7a9ac9a093335806694ecd6d4edc0d6a8", - "integrity": "sha256-qljzPyOaD7AvXHpsRcBD16msmgkzNYBmlOzW1O3A1qg=" - }, - "font-awesome/fontawesome-webfont-ad6157926c1622ba4e1d03d478f1541368524bfc46f51e42fe0d945f7ef323e4.svg": { - "logical_path": "font-awesome/fontawesome-webfont.svg", - "mtime": "2019-08-14T17:22:43+08:00", - "size": 444379, - "digest": "ad6157926c1622ba4e1d03d478f1541368524bfc46f51e42fe0d945f7ef323e4", - "integrity": "sha256-rWFXkmwWIrpOHQPUePFUE2hSS/xG9R5C/g2UX37zI+Q=" - }, - "college-18f5e8400331634e898a35acc2187815c096c25e0ab74aba341ae916166cd287.js": { - "logical_path": "college.js", - "mtime": "2019-10-24T15:25:17+08:00", - "size": 3352744, - "digest": "18f5e8400331634e898a35acc2187815c096c25e0ab74aba341ae916166cd287", - "integrity": "sha256-GPXoQAMxY06JijWswhh4FcCWwl4Kt0q6NBrpFhZs0oc=" - }, - "college-944d4273f62c7538368b9017fdd3387b5e3bea31a87873770eb231324546d4d9.css": { - "logical_path": "college.css", - "mtime": "2019-09-11T16:20:07+08:00", - "size": 546841, - "digest": "944d4273f62c7538368b9017fdd3387b5e3bea31a87873770eb231324546d4d9", - "integrity": "sha256-lE1Cc/YsdTg2i5AX/dM4e1476jGoeHN3DrIxMkVG1Nk=" - }, - "logo-7ff112568709bf97f9898fe87249b7a8f200ff1f48d537d85af87215f1870423.png": { - "logical_path": "logo.png", - "mtime": "2019-09-03T08:55:53+08:00", - "size": 2816, - "digest": "7ff112568709bf97f9898fe87249b7a8f200ff1f48d537d85af87215f1870423", - "integrity": "sha256-f/ESVocJv5f5iY/ockm3qPIA/x9I1TfYWvhyFfGHBCM=" - }, - "application-9cfbc3d792599a1d0de5c7b84209e1c2b2e60336f0f01e19f0581663918708fb.js": { - "logical_path": "application.js", - "mtime": "2019-10-24T15:25:17+08:00", - "size": 600706, - "digest": "9cfbc3d792599a1d0de5c7b84209e1c2b2e60336f0f01e19f0581663918708fb", - "integrity": "sha256-nPvD15JZmh0N5ce4QgnhwrLmAzbw8B4Z8FgWY5GHCPs=" - }, - "application-5eb87c6e13676d0183317debce17fade27e68c4acee28c419438da15d53c94f2.css": { - "logical_path": "application.css", - "mtime": "2019-09-11T16:20:07+08:00", - "size": 1844002, - "digest": "5eb87c6e13676d0183317debce17fade27e68c4acee28c419438da15d53c94f2", - "integrity": "sha256-Xrh8bhNnbQGDMX3rzhf63ifmjErO4oxBlDjaFdU8lPI=" - }, - "admin-c9e5ebe6191548550e27514196ea125cfbb402820ec125a0c9acf99d2d378fe4.js": { - "logical_path": "admin.js", - "mtime": "2019-09-21T15:28:08+08:00", - "size": 4382031, - "digest": "c9e5ebe6191548550e27514196ea125cfbb402820ec125a0c9acf99d2d378fe4", - "integrity": "sha256-yeXr5hkVSFUOJ1FBluoSXPu0AoIOwSWgyaz5nS03j+Q=" - }, - "admin-59c59f8cae8bef4a8359286c985458110c9d03ea121516595c988943f4717c38.css": { - "logical_path": "admin.css", - "mtime": "2019-09-21T14:49:04+08:00", - "size": 840093, - "digest": "59c59f8cae8bef4a8359286c985458110c9d03ea121516595c988943f4717c38", - "integrity": "sha256-WcWfjK6L70qDWShsmFRYEQydA+oSFRZZXJiJQ/RxfDg=" - }, - "college-38f953d6ba5b85d3fab63cb3c2bbf0d057ccc6454d07cfaafac3b06da37b8437.css": { - "logical_path": "college.css", - "mtime": "2019-09-16T13:56:09+08:00", - "size": 579109, - "digest": "38f953d6ba5b85d3fab63cb3c2bbf0d057ccc6454d07cfaafac3b06da37b8437", - "integrity": "sha256-OPlT1rpbhdP6tjyzwrvw0FfMxkVNB8+q+sOwbaN7hDc=" - }, - "application-646b1158a4e8c1f13e684d6fe9025abc75f8d3ba5256e440802c0398223374f3.css": { - "logical_path": "application.css", - "mtime": "2019-09-21T14:49:04+08:00", - "size": 1988767, - "digest": "646b1158a4e8c1f13e684d6fe9025abc75f8d3ba5256e440802c0398223374f3", - "integrity": "sha256-ZGsRWKTowfE+aE1v6QJavHX407pSVuRAgCwDmCIzdPM=" - }, - "admin-a47e37c0ec7cf5f22380249776d1e82d65b6b6aa272ed7389185aa200fa40751.js": { - "logical_path": "admin.js", - "mtime": "2019-09-25T15:33:05+08:00", - "size": 4383107, - "digest": "a47e37c0ec7cf5f22380249776d1e82d65b6b6aa272ed7389185aa200fa40751", - "integrity": "sha256-pH43wOx89fIjgCSXdtHoLWW2tqonLtc4kYWqIA+kB1E=" - }, - "admin-432c4eac09b036c57ff1e88d902b8aa7df81164e4b419bac557cf1366c1d3ad9.js": { - "logical_path": "admin.js", - "mtime": "2019-09-25T15:35:20+08:00", - "size": 4383103, - "digest": "432c4eac09b036c57ff1e88d902b8aa7df81164e4b419bac557cf1366c1d3ad9", - "integrity": "sha256-QyxOrAmwNsV/8eiNkCuKp9+BFk5LQZusVXzxNmwdOtk=" - }, - "admin-978e5ce607f77c26814a174f480da79ac246c2201868ef84654aa03bb6727b5a.js": { - "logical_path": "admin.js", - "mtime": "2019-09-30T14:43:41+08:00", - "size": 4387200, - "digest": "978e5ce607f77c26814a174f480da79ac246c2201868ef84654aa03bb6727b5a", - "integrity": "sha256-l45c5gf3fCaBShdPSA2nmsJGwiAYaO+EZUqgO7Zye1o=" - }, - "admin-896281f4731722b0c084dbb1af21d0f34a5bc142d58aff57b391864ab71ddca7.css": { - "logical_path": "admin.css", - "mtime": "2019-09-30T14:43:41+08:00", - "size": 842269, - "digest": "896281f4731722b0c084dbb1af21d0f34a5bc142d58aff57b391864ab71ddca7", - "integrity": "sha256-iWKB9HMXIrDAhNuxryHQ80pbwULViv9Xs5GGSrcd3Kc=" - }, - "application-97f313e9bb7d25476649f7d7215959cf421480fd0a3785d1956953bf94a1e8bd.css": { - "logical_path": "application.css", - "mtime": "2019-09-30T14:43:41+08:00", - "size": 1993118, - "digest": "97f313e9bb7d25476649f7d7215959cf421480fd0a3785d1956953bf94a1e8bd", - "integrity": "sha256-l/MT6bt9JUdmSffXIVlZz0IUgP0KN4XRlWlTv5Sh6L0=" - }, - "admin-2cdb23442fa735025385b88f2900df04fef38b61530041a6dbe375ef0f0ae888.js": { - "logical_path": "admin.js", - "mtime": "2019-10-11T14:38:33+08:00", - "size": 4394616, - "digest": "2cdb23442fa735025385b88f2900df04fef38b61530041a6dbe375ef0f0ae888", - "integrity": "sha256-LNsjRC+nNQJThbiPKQDfBP7zi2FTAEGm2+N17w8K6Ig=" - }, - "admin-2c2854b9a02158ded5a809aaf7144a8630b10354ab4e56fecc4dffcc713796cc.css": { - "logical_path": "admin.css", - "mtime": "2019-10-10T17:12:05+08:00", - "size": 846514, - "digest": "2c2854b9a02158ded5a809aaf7144a8630b10354ab4e56fecc4dffcc713796cc", - "integrity": "sha256-LChUuaAhWN7VqAmq9xRKhjCxA1SrTlb+zE3/zHE3lsw=" - }, - "application-50059ae929866043b47015128702fcfba53d32a2df148e64e1d961c10651c6af.css": { - "logical_path": "application.css", - "mtime": "2019-10-10T17:12:05+08:00", - "size": 2001607, - "digest": "50059ae929866043b47015128702fcfba53d32a2df148e64e1d961c10651c6af", - "integrity": "sha256-UAWa6SmGYEO0cBUShwL8+6U9MqLfFI5k4dlhwQZRxq8=" - }, - "admin-992cde09b6d17f00a49576ae2d9f1ced127244ba401ef5b7d677cab9741688d2.js": { - "logical_path": "admin.js", - "mtime": "2019-10-16T16:11:32+08:00", - "size": 4394790, - "digest": "992cde09b6d17f00a49576ae2d9f1ced127244ba401ef5b7d677cab9741688d2", - "integrity": "sha256-mSzeCbbRfwCklXauLZ8c7RJyRLpAHvW31nfKuXQWiNI=" - }, - "admin-84f2a7791e275d6f820514370b3f968176b994b9dd7b8c3ba8bf48336b03f257.css": { - "logical_path": "admin.css", - "mtime": "2019-10-16T19:25:40+08:00", - "size": 846676, - "digest": "84f2a7791e275d6f820514370b3f968176b994b9dd7b8c3ba8bf48336b03f257", - "integrity": "sha256-hPKneR4nXW+CBRQ3Cz+WgXa5lLnde4w7qL9IM2sD8lc=" - }, - "application-ef6bab84852baaf69a91fe6af875b6e1b118c55b4c7d165665c488fac80c4997.css": { - "logical_path": "application.css", - "mtime": "2019-10-16T19:25:40+08:00", - "size": 2001931, - "digest": "ef6bab84852baaf69a91fe6af875b6e1b118c55b4c7d165665c488fac80c4997", - "integrity": "sha256-72urhIUrqvaakf5q+HW24bEYxVtMfRZWZcSI+sgMSZc=" - }, - "admin-c99030d305662f740aa84b6c925a1adbbaadaa07fd74e2655e64d44b4b97fc4a.js": { - "logical_path": "admin.js", - "mtime": "2019-10-17T09:44:58+08:00", - "size": 4394897, - "digest": "c99030d305662f740aa84b6c925a1adbbaadaa07fd74e2655e64d44b4b97fc4a", - "integrity": "sha256-yZAw0wVmL3QKqEtskloa27qtqgf9dOJlXmTUS0uX/Eo=" - }, - "admin-534bde871d67f4d6fc8da611917d78be4066fc7593ba53ee92aa17068a199d6d.css": { - "logical_path": "admin.css", - "mtime": "2019-10-17T10:22:41+08:00", - "size": 846699, - "digest": "534bde871d67f4d6fc8da611917d78be4066fc7593ba53ee92aa17068a199d6d", - "integrity": "sha256-U0vehx1n9Nb8jaYRkX14vkBm/HWTulPukqoXBooZnW0=" - }, - "cooperative-04cd6a60d41220d38ee45ce40b1d004e1d0bcd87c132fb1a7bab6144c1deb8d7.js": { - "logical_path": "cooperative.js", - "mtime": "2019-10-17T10:17:56+08:00", - "size": 4330072, - "digest": "04cd6a60d41220d38ee45ce40b1d004e1d0bcd87c132fb1a7bab6144c1deb8d7", - "integrity": "sha256-BM1qYNQSINOO5FzkCx0ATh0LzYfBMvsae6thRMHeuNc=" - }, - "cooperative-a345bbfd8e38b70c9285ecc1747012ffcde429187983e2aea5657abb56b9b4f3.css": { - "logical_path": "cooperative.css", - "mtime": "2019-10-17T10:21:41+08:00", - "size": 830628, - "digest": "a345bbfd8e38b70c9285ecc1747012ffcde429187983e2aea5657abb56b9b4f3", - "integrity": "sha256-o0W7/Y44twyShezBdHAS/83kKRh5g+KupWV6u1a5tPM=" - }, - "application-0e417478d56f42467e857cd186b29cbbc0d6c7c6e85c8a6f42f39ac618943de8.css": { - "logical_path": "application.css", - "mtime": "2019-09-03T08:55:53+08:00", - "size": 442932, - "digest": "0e417478d56f42467e857cd186b29cbbc0d6c7c6e85c8a6f42f39ac618943de8", - "integrity": "sha256-DkF0eNVvQkZ+hXzRhrKcu8DWx8boXIpvQvOaxhiUPeg=" - }, - "cooperative-149f47b8675d60a8014ccff50f00f932ff69e2be286ffb74343bc4a3effb135b.js": { - "logical_path": "cooperative.js", - "mtime": "2019-10-17T14:03:03+08:00", - "size": 4338033, - "digest": "149f47b8675d60a8014ccff50f00f932ff69e2be286ffb74343bc4a3effb135b", - "integrity": "sha256-FJ9HuGddYKgBTM/1DwD5Mv9p4r4ob/t0NDvEo+/7E1s=" - }, - "cooperative-6273b766d6ef11dd56174d868bab55e7f17af17546c888d2ba0dd0a6bcda76c8.css": { - "logical_path": "cooperative.css", - "mtime": "2019-10-17T11:13:07+08:00", - "size": 832914, - "digest": "6273b766d6ef11dd56174d868bab55e7f17af17546c888d2ba0dd0a6bcda76c8", - "integrity": "sha256-YnO3ZtbvEd1WF02Gi6tV5/F68XVGyIjSug3Qprzadsg=" - }, - "admin-82f66cc80b5649c6530a562567f28fe8d05f7bc3b8221e0695b2216255c52ba6.js": { - "logical_path": "admin.js", - "mtime": "2019-10-21T13:51:43+08:00", - "size": 4397012, - "digest": "82f66cc80b5649c6530a562567f28fe8d05f7bc3b8221e0695b2216255c52ba6", - "integrity": "sha256-gvZsyAtWScZTClYlZ/KP6NBfe8O4Ih4GlbIhYlXFK6Y=" - }, - "admin-1b5728d94f6bccfbcef452a760d94c3b6f31966bc65d7f89be077fc2ea512bec.js": { - "logical_path": "admin.js", - "mtime": "2019-10-21T16:41:06+08:00", - "size": 4397437, - "digest": "1b5728d94f6bccfbcef452a760d94c3b6f31966bc65d7f89be077fc2ea512bec", - "integrity": "sha256-G1co2U9rzPvO9FKnYNlMO28xlmvGXX+Jvgd/wupRK+w=" - }, - "admin-c8c127fefa5eca98bca19832c246619318164e8f242635c07033e2423cc18a6f.js": { - "logical_path": "admin.js", - "mtime": "2019-10-22T09:53:29+08:00", - "size": 4408150, - "digest": "c8c127fefa5eca98bca19832c246619318164e8f242635c07033e2423cc18a6f", - "integrity": "sha256-yMEn/vpeypi8oZgywkZhkxgWTo8kJjXAcDPiQjzBim8=" - }, - "admin-60d200c1fcdf61a60537d29ccf4479c6b1e5e904208870a63b8ee677c96b347e.css": { - "logical_path": "admin.css", - "mtime": "2019-10-22T09:43:20+08:00", - "size": 851150, - "digest": "60d200c1fcdf61a60537d29ccf4479c6b1e5e904208870a63b8ee677c96b347e", - "integrity": "sha256-YNIAwfzfYaYFN9Kcz0R5xrHl6QQgiHCmO47md8lrNH4=" - }, - "cooperative-9fb7ac4ad44081fafd5ad2a3a1bfb7f4329ac96f28bc6446d1ff52b1e2e71286.js": { - "logical_path": "cooperative.js", - "mtime": "2019-10-22T09:55:26+08:00", - "size": 4338142, - "digest": "9fb7ac4ad44081fafd5ad2a3a1bfb7f4329ac96f28bc6446d1ff52b1e2e71286", - "integrity": "sha256-n7esStRAgfr9WtKjob+39DKayW8ovGRG0f9SseLnEoY=" - }, - "admin-a11066081d60365ddf25d5867560d1ccdd3197dbe82a5b6e969cc940e3429ff1.js": { - "logical_path": "admin.js", - "mtime": "2019-10-24T14:16:30+08:00", - "size": 4524252, - "digest": "a11066081d60365ddf25d5867560d1ccdd3197dbe82a5b6e969cc940e3429ff1", - "integrity": "sha256-oRBmCB1gNl3fJdWGdWDRzN0xl9voKltulpzJQONCn/E=" - }, - "admin-7ce3dd717f7d12fcbc64caf14200230a1e68db439be0ba1879077599ff2c32c6.css": { - "logical_path": "admin.css", - "mtime": "2019-10-24T10:10:08+08:00", - "size": 852772, - "digest": "7ce3dd717f7d12fcbc64caf14200230a1e68db439be0ba1879077599ff2c32c6", - "integrity": "sha256-fOPdcX99Evy8ZMrxQgAjCh5o20Ob4LoYeQd1mf8sMsY=" - }, - "college-93904c65d52c125aec0a463b9fd98bedda0018b78707f806be22685cca5d3747.css": { - "logical_path": "college.css", - "mtime": "2019-10-24T10:10:08+08:00", - "size": 579546, - "digest": "93904c65d52c125aec0a463b9fd98bedda0018b78707f806be22685cca5d3747", - "integrity": "sha256-k5BMZdUsElrsCkY7n9mL7doAGLeHB/gGviJoXMpdN0c=" - }, - "cooperative-84c79d26a36aff5b496551b6d21b1bfb726b1bbc4153435a366115e96c204e06.js": { - "logical_path": "cooperative.js", - "mtime": "2019-10-24T14:17:15+08:00", - "size": 4338225, - "digest": "84c79d26a36aff5b496551b6d21b1bfb726b1bbc4153435a366115e96c204e06", - "integrity": "sha256-hMedJqNq/1tJZVG20hsb+3JrG7xBU0NaNmEV6WwgTgY=" - }, - "cooperative-10a9ee5177e196572573ccea460e133c748072e223fdb473d05ee72c991fbbe3.css": { - "logical_path": "cooperative.css", - "mtime": "2019-10-24T10:10:08+08:00", - "size": 833351, - "digest": "10a9ee5177e196572573ccea460e133c748072e223fdb473d05ee72c991fbbe3", - "integrity": "sha256-EKnuUXfhllclc8zqRg4TPHSAcuIj/bRz0F7nLJkfu+M=" - }, - "admin-441d8f3722e5f73e5748aaeb6f517101474cb1eb48a99f119e561f08b9e9dc60.js": { - "logical_path": "admin.js", - "mtime": "2019-10-24T16:08:56+08:00", - "size": 4525031, - "digest": "441d8f3722e5f73e5748aaeb6f517101474cb1eb48a99f119e561f08b9e9dc60", - "integrity": "sha256-RB2PNyLl9z5XSKrrb1FxAUdMsetIqZ8RnlYfCLnp3GA=" - }, - "admin-76c52986591f274f639ad48dfbb480a1aeeec7647b6fa28fa541e78a064b6316.css": { - "logical_path": "admin.css", - "mtime": "2019-10-24T15:25:17+08:00", - "size": 867945, - "digest": "76c52986591f274f639ad48dfbb480a1aeeec7647b6fa28fa541e78a064b6316", - "integrity": "sha256-dsUphlkfJ09jmtSN+7SAoa7ux2R7b6KPpUHnigZLYxY=" - }, - "cooperative-6c4c663b6b5071535bab2b76cc5e05ab5682665857763a76bf4f01afef51be5a.js": { - "logical_path": "cooperative.js", - "mtime": "2019-10-24T17:56:20+08:00", - "size": 4339039, - "digest": "6c4c663b6b5071535bab2b76cc5e05ab5682665857763a76bf4f01afef51be5a", - "integrity": "sha256-bExmO2tQcVNbqyt2zF4Fq1aCZlhXdjp2v08Br+9Rvlo=" - }, - "admin-c63acadd431434979db50540a0bf7e65c75e1de0d1b449919f2cce89a0548d43.js": { - "logical_path": "admin.js", - "mtime": "2019-10-24T18:12:33+08:00", - "size": 4533182, - "digest": "c63acadd431434979db50540a0bf7e65c75e1de0d1b449919f2cce89a0548d43", - "integrity": "sha256-xjrK3UMUNJedtQVAoL9+ZcdeHeDRtEmRnyzOiaBUjUM=" - }, - "admin-bd832b9a35eb3743dde9218beab61f9bcde1508767ad68dbedb1c89a4bb65c3a.css": { - "logical_path": "admin.css", - "mtime": "2019-10-24T17:56:20+08:00", - "size": 861450, - "digest": "bd832b9a35eb3743dde9218beab61f9bcde1508767ad68dbedb1c89a4bb65c3a", - "integrity": "sha256-vYMrmjXrN0Pd6SGL6rYfm83hUIdnrWjb7bHImku2XDo=" - }, - "college-fa202780f3e7f96cb9b5916c6f0d7dd9e03cb746864bbd2dd491ed001c30ad8f.css": { - "logical_path": "college.css", - "mtime": "2019-10-24T17:56:20+08:00", - "size": 571936, - "digest": "fa202780f3e7f96cb9b5916c6f0d7dd9e03cb746864bbd2dd491ed001c30ad8f", - "integrity": "sha256-+iAngPPn+Wy5tZFsbw192eA8t0aGS70t1JHtABwwrY8=" - }, - "cooperative-4f233e8963b0bd80bc56b71c209d31464d314240ac8d686806baf99511c53ad0.css": { - "logical_path": "cooperative.css", - "mtime": "2019-10-24T17:56:20+08:00", - "size": 825741, - "digest": "4f233e8963b0bd80bc56b71c209d31464d314240ac8d686806baf99511c53ad0", - "integrity": "sha256-TyM+iWOwvYC8VrccIJ0xRk0xQkCsjWhoBrr5lRHFOtA=" - }, - "application-8c9d6bb61c50908f584b3070c79aeb95f25c1166d39e07da5e95438b39ca0de9.css": { - "logical_path": "application.css", - "mtime": "2019-10-21T22:52:15+08:00", - "size": 436995, - "digest": "8c9d6bb61c50908f584b3070c79aeb95f25c1166d39e07da5e95438b39ca0de9", - "integrity": "sha256-jJ1rthxQkI9YSzBwx5rrlfJcEWbTngfaXpVDiznKDek=" - }, - "admin-bf2bd889f02d15c4913aa260497d72afeb26d701aac49a4ef6a75619af030152.js": { - "logical_path": "admin.js", - "mtime": "2019-10-25T10:12:17+08:00", - "size": 4533673, - "digest": "bf2bd889f02d15c4913aa260497d72afeb26d701aac49a4ef6a75619af030152", - "integrity": "sha256-vyvYifAtFcSROqJgSX1yr+sm1wGqxJpO9qdWGa8DAVI=" - }, - "admin-46e564d29ffae5c71ae9b5e36dc0bd5de57b10f396eb2005bfb9cf51e7744cdd.css": { - "logical_path": "admin.css", - "mtime": "2019-10-25T10:12:17+08:00", - "size": 870355, - "digest": "46e564d29ffae5c71ae9b5e36dc0bd5de57b10f396eb2005bfb9cf51e7744cdd", - "integrity": "sha256-RuVk0p/65cca6bXjbcC9XeV7EPOW6yAFv7nPUed0TN0=" - }, - "college-2299e05f5e9b640e333ece624d4ab18a678fdabff0bc18b69a9c2e3de49cba8e.css": { - "logical_path": "college.css", - "mtime": "2019-10-25T10:12:17+08:00", - "size": 580077, - "digest": "2299e05f5e9b640e333ece624d4ab18a678fdabff0bc18b69a9c2e3de49cba8e", - "integrity": "sha256-IpngX16bZA4zPs5iTUqximeP2r/wvBi2mpwuPeScuo4=" - }, - "cooperative-f1ac8f14ad6ade8d1f79ca49ea9c79be77d49aae9d2705ca672e78444481700d.js": { - "logical_path": "cooperative.js", - "mtime": "2019-10-25T11:01:38+08:00", - "size": 4409145, - "digest": "f1ac8f14ad6ade8d1f79ca49ea9c79be77d49aae9d2705ca672e78444481700d", - "integrity": "sha256-8ayPFK1q3o0fecpJ6px5vnfUmq6dJwXKZy54RESBcA0=" - }, - "cooperative-8057adee2454dbc9d648305faf9ede9824f40d3bd0184e816e8035bb7f1e730b.css": { - "logical_path": "cooperative.css", - "mtime": "2019-10-25T10:12:17+08:00", - "size": 833882, - "digest": "8057adee2454dbc9d648305faf9ede9824f40d3bd0184e816e8035bb7f1e730b", - "integrity": "sha256-gFet7iRU28nWSDBfr57emCT0DTvQGE6BboA1u38ecws=" - }, - "admin-6f9bb9720e7e5040ae559a8fae11553313f77552a76416b3a9fe77198471964d.js": { - "logical_path": "admin.js", - "mtime": "2019-10-25T17:00:09+08:00", - "size": 4554537, - "digest": "6f9bb9720e7e5040ae559a8fae11553313f77552a76416b3a9fe77198471964d", - "integrity": "sha256-b5u5cg5+UECuVZqPrhFVMxP3dVKnZBazqf53GYRxlk0=" - }, - "admin-ab3e0f7240ae4df8d1585c8d5e99df41edd3305ecc2abadcf8820796e1d9fc65.css": { - "logical_path": "admin.css", - "mtime": "2019-10-25T09:55:22+08:00", - "size": 862288, - "digest": "ab3e0f7240ae4df8d1585c8d5e99df41edd3305ecc2abadcf8820796e1d9fc65", - "integrity": "sha256-qz4PckCuTfjRWFyNXpnfQe3TMF7MKrrc+IIHluHZ/GU=" - }, - "college-2fdfc5431b46ad4a454a25386dbcbc390466886f76b85fdb7e3f75018196a870.css": { - "logical_path": "college.css", - "mtime": "2019-10-25T09:55:22+08:00", - "size": 572010, - "digest": "2fdfc5431b46ad4a454a25386dbcbc390466886f76b85fdb7e3f75018196a870", - "integrity": "sha256-L9/FQxtGrUpFSiU4bby8OQRmiG92uF/bfj91AYGWqHA=" - }, - "cooperative-47d516a0904d0633e82c1de39a6ec4c9e6de0a37813843e01d4bacf97e8b2ebf.css": { - "logical_path": "cooperative.css", - "mtime": "2019-10-25T09:55:22+08:00", - "size": 825815, - "digest": "47d516a0904d0633e82c1de39a6ec4c9e6de0a37813843e01d4bacf97e8b2ebf", - "integrity": "sha256-R9UWoJBNBjPoLB3jmm7EyebeCjeBOEPgHUus+X6LLr8=" - }, - "admin-839af7c0d2917a8f8019d0376ea17cec050ef4d19d98c6c10de91f5d2bc81adf.js": { - "logical_path": "admin.js", - "mtime": "2019-10-26T11:25:08+08:00", - "size": 4554543, - "digest": "839af7c0d2917a8f8019d0376ea17cec050ef4d19d98c6c10de91f5d2bc81adf", - "integrity": "sha256-g5r3wNKReo+AGdA3bqF87AUO9NGdmMbBDekfXSvIGt8=" - }, - "admin-52d692608c620ae47717a2ac88377e55b9b58af0acdf3f777814a1fd47b6594b.js": { - "logical_path": "admin.js", - "mtime": "2019-10-26T17:16:18+08:00", - "size": 4553202, - "digest": "52d692608c620ae47717a2ac88377e55b9b58af0acdf3f777814a1fd47b6594b", - "integrity": "sha256-UtaSYIxiCuR3F6KsiDd+Vbm1ivCs3z93eBSh/Ue2WUs=" - }, - "admin-b58555ae641bbaa61e3af0ddd2756acc3c5de9023c737815c72132cc67c9a403.js": { - "logical_path": "admin.js", - "mtime": "2019-10-27T13:06:02+08:00", - "size": 4553607, - "digest": "b58555ae641bbaa61e3af0ddd2756acc3c5de9023c737815c72132cc67c9a403", - "integrity": "sha256-tYVVrmQbuqYeOvDd0nVqzDxd6QI8c3gVxyEyzGfJpAM=" - }, - "admin-b95c48ea51f392ce7c4024d0d8b2c42dfe48528a1898ec3f7818e0cda2a4f224.js": { - "logical_path": "admin.js", - "mtime": "2019-10-28T10:46:29+08:00", - "size": 4554008, - "digest": "b95c48ea51f392ce7c4024d0d8b2c42dfe48528a1898ec3f7818e0cda2a4f224", - "integrity": "sha256-uVxI6lHzks58QCTQ2LLELf5IUooYmOw/eBjgzaKk8iQ=" - }, - "admin-1f2e5a2a28462df8bcddfbdbfbebdc36a761ca7a94962ae71d37fb8c06fc5f94.js": { - "logical_path": "admin.js", - "mtime": "2019-10-29T08:57:11+08:00", - "size": 4554938, - "digest": "1f2e5a2a28462df8bcddfbdbfbebdc36a761ca7a94962ae71d37fb8c06fc5f94", - "integrity": "sha256-Hy5aKihGLfi83fvb++vcNqdhynqUlirnHTf7jAb8X5Q=" - }, - "admin-cb3d4541758ef2bcbfe16f518d48f85097d0547a587de222d2fc13dbdd474b4b.js": { - "logical_path": "admin.js", - "mtime": "2019-10-29T14:06:13+08:00", - "size": 4556541, - "digest": "cb3d4541758ef2bcbfe16f518d48f85097d0547a587de222d2fc13dbdd474b4b", - "integrity": "sha256-yz1FQXWO8ry/4W9RjUj4UJfQVHpYfeIi0vwT291HS0s=" - }, - "admin-6a76c25b6691b4f436608be28606d90c907ba8f033f5f47c6c20d7bf11251cb6.css": { - "logical_path": "admin.css", - "mtime": "2019-10-29T14:22:47+08:00", - "size": 871031, - "digest": "6a76c25b6691b4f436608be28606d90c907ba8f033f5f47c6c20d7bf11251cb6", - "integrity": "sha256-anbCW2aRtPQ2YIvihgbZDJB7qPAz9fR8bCDXvxElHLY=" - }, - "admin-ba909dfe0de4d216bedb3c743144321e4023837568abab1d3ee9a28b2faa5925.js": { - "logical_path": "admin.js", - "mtime": "2019-10-29T14:43:01+08:00", - "size": 4556622, - "digest": "ba909dfe0de4d216bedb3c743144321e4023837568abab1d3ee9a28b2faa5925", - "integrity": "sha256-upCd/g3k0ha+2zx0MUQyHkAjg3Voq6sdPumiiy+qWSU=" - }, - "admin-e975e2039206e9ae2b6a072fee083cf39b8e04f2318f67bfbf1923fe208456b3.js": { - "logical_path": "admin.js", - "mtime": "2019-10-29T15:50:27+08:00", - "size": 4559454, - "digest": "e975e2039206e9ae2b6a072fee083cf39b8e04f2318f67bfbf1923fe208456b3", - "integrity": "sha256-6XXiA5IG6a4ragcv7gg885uOBPIxj2e/vxkj/iCEVrM=" - }, - "cooperative-a309d245cd0b0b9c653db471c53ec090e49ba7ad885879ffa02a11b6efd79d74.js": { - "logical_path": "cooperative.js", - "mtime": "2019-10-29T15:50:27+08:00", - "size": 4409163, - "digest": "a309d245cd0b0b9c653db471c53ec090e49ba7ad885879ffa02a11b6efd79d74", - "integrity": "sha256-ownSRc0LC5xlPbRxxT7AkOSbp62IWHn/oCoRtu/XnXQ=" - } - }, - "assets": { - "admin.js": "admin-e975e2039206e9ae2b6a072fee083cf39b8e04f2318f67bfbf1923fe208456b3.js", - "admin.css": "admin-6a76c25b6691b4f436608be28606d90c907ba8f033f5f47c6c20d7bf11251cb6.css", - "font-awesome/fontawesome-webfont.eot": "font-awesome/fontawesome-webfont-7bfcab6db99d5cfbf1705ca0536ddc78585432cc5fa41bbd7ad0f009033b2979.eot", - "font-awesome/fontawesome-webfont.woff2": "font-awesome/fontawesome-webfont-2adefcbc041e7d18fcf2d417879dc5a09997aa64d675b7a3c4b6ce33da13f3fe.woff2", - "font-awesome/fontawesome-webfont.woff": "font-awesome/fontawesome-webfont-ba0c59deb5450f5cb41b3f93609ee2d0d995415877ddfa223e8a8a7533474f07.woff", - "font-awesome/fontawesome-webfont.ttf": "font-awesome/fontawesome-webfont-aa58f33f239a0fb02f5c7a6c45c043d7a9ac9a093335806694ecd6d4edc0d6a8.ttf", - "font-awesome/fontawesome-webfont.svg": "font-awesome/fontawesome-webfont-ad6157926c1622ba4e1d03d478f1541368524bfc46f51e42fe0d945f7ef323e4.svg", - "college.js": "college-18f5e8400331634e898a35acc2187815c096c25e0ab74aba341ae916166cd287.js", - "college.css": "college-2299e05f5e9b640e333ece624d4ab18a678fdabff0bc18b69a9c2e3de49cba8e.css", - "logo.png": "logo-7ff112568709bf97f9898fe87249b7a8f200ff1f48d537d85af87215f1870423.png", - "application.js": "application-9cfbc3d792599a1d0de5c7b84209e1c2b2e60336f0f01e19f0581663918708fb.js", - "application.css": "application-0e417478d56f42467e857cd186b29cbbc0d6c7c6e85c8a6f42f39ac618943de8.css", - "cooperative.js": "cooperative-a309d245cd0b0b9c653db471c53ec090e49ba7ad885879ffa02a11b6efd79d74.js", - "cooperative.css": "cooperative-8057adee2454dbc9d648305faf9ede9824f40d3bd0184e816e8035bb7f1e730b.css" - } -} +{"files":{"admin-cd9ca8bacc973ce2dbace30c97f6c40bc08e2c2ee44972f668e738e1902c0121.js":{"logical_path":"admin.js","mtime":"2019-09-11T16:20:07+08:00","size":4350881,"digest":"cd9ca8bacc973ce2dbace30c97f6c40bc08e2c2ee44972f668e738e1902c0121","integrity":"sha256-zZyousyXPOLbrOMMl/bEC8COLC7kSXL2aOc44ZAsASE="},"admin-a1b3356efe50ff4717cf22475639b5333c5354ba03fd107c9b7a8d4ae76f47aa.css":{"logical_path":"admin.css","mtime":"2019-09-11T16:20:07+08:00","size":773445,"digest":"a1b3356efe50ff4717cf22475639b5333c5354ba03fd107c9b7a8d4ae76f47aa","integrity":"sha256-obM1bv5Q/0cXzyJHVjm1MzxTVLoD/RB8m3qNSudvR6o="},"font-awesome/fontawesome-webfont-7bfcab6db99d5cfbf1705ca0536ddc78585432cc5fa41bbd7ad0f009033b2979.eot":{"logical_path":"font-awesome/fontawesome-webfont.eot","mtime":"2019-08-14T17:22:43+08:00","size":165742,"digest":"7bfcab6db99d5cfbf1705ca0536ddc78585432cc5fa41bbd7ad0f009033b2979","integrity":"sha256-e/yrbbmdXPvxcFygU23ceFhUMsxfpBu9etDwCQM7KXk="},"font-awesome/fontawesome-webfont-2adefcbc041e7d18fcf2d417879dc5a09997aa64d675b7a3c4b6ce33da13f3fe.woff2":{"logical_path":"font-awesome/fontawesome-webfont.woff2","mtime":"2019-08-14T17:22:43+08:00","size":77160,"digest":"2adefcbc041e7d18fcf2d417879dc5a09997aa64d675b7a3c4b6ce33da13f3fe","integrity":"sha256-Kt78vAQefRj88tQXh53FoJmXqmTWdbejxLbOM9oT8/4="},"font-awesome/fontawesome-webfont-ba0c59deb5450f5cb41b3f93609ee2d0d995415877ddfa223e8a8a7533474f07.woff":{"logical_path":"font-awesome/fontawesome-webfont.woff","mtime":"2019-08-14T17:22:43+08:00","size":98024,"digest":"ba0c59deb5450f5cb41b3f93609ee2d0d995415877ddfa223e8a8a7533474f07","integrity":"sha256-ugxZ3rVFD1y0Gz+TYJ7i0NmVQVh33foiPoqKdTNHTwc="},"font-awesome/fontawesome-webfont-aa58f33f239a0fb02f5c7a6c45c043d7a9ac9a093335806694ecd6d4edc0d6a8.ttf":{"logical_path":"font-awesome/fontawesome-webfont.ttf","mtime":"2019-08-14T17:22:43+08:00","size":165548,"digest":"aa58f33f239a0fb02f5c7a6c45c043d7a9ac9a093335806694ecd6d4edc0d6a8","integrity":"sha256-qljzPyOaD7AvXHpsRcBD16msmgkzNYBmlOzW1O3A1qg="},"font-awesome/fontawesome-webfont-ad6157926c1622ba4e1d03d478f1541368524bfc46f51e42fe0d945f7ef323e4.svg":{"logical_path":"font-awesome/fontawesome-webfont.svg","mtime":"2019-08-14T17:22:43+08:00","size":444379,"digest":"ad6157926c1622ba4e1d03d478f1541368524bfc46f51e42fe0d945f7ef323e4","integrity":"sha256-rWFXkmwWIrpOHQPUePFUE2hSS/xG9R5C/g2UX37zI+Q="},"college-18f5e8400331634e898a35acc2187815c096c25e0ab74aba341ae916166cd287.js":{"logical_path":"college.js","mtime":"2019-10-24T15:25:17+08:00","size":3352744,"digest":"18f5e8400331634e898a35acc2187815c096c25e0ab74aba341ae916166cd287","integrity":"sha256-GPXoQAMxY06JijWswhh4FcCWwl4Kt0q6NBrpFhZs0oc="},"college-944d4273f62c7538368b9017fdd3387b5e3bea31a87873770eb231324546d4d9.css":{"logical_path":"college.css","mtime":"2019-09-11T16:20:07+08:00","size":546841,"digest":"944d4273f62c7538368b9017fdd3387b5e3bea31a87873770eb231324546d4d9","integrity":"sha256-lE1Cc/YsdTg2i5AX/dM4e1476jGoeHN3DrIxMkVG1Nk="},"logo-7ff112568709bf97f9898fe87249b7a8f200ff1f48d537d85af87215f1870423.png":{"logical_path":"logo.png","mtime":"2019-09-03T08:55:53+08:00","size":2816,"digest":"7ff112568709bf97f9898fe87249b7a8f200ff1f48d537d85af87215f1870423","integrity":"sha256-f/ESVocJv5f5iY/ockm3qPIA/x9I1TfYWvhyFfGHBCM="},"application-9cfbc3d792599a1d0de5c7b84209e1c2b2e60336f0f01e19f0581663918708fb.js":{"logical_path":"application.js","mtime":"2019-10-24T15:25:17+08:00","size":600706,"digest":"9cfbc3d792599a1d0de5c7b84209e1c2b2e60336f0f01e19f0581663918708fb","integrity":"sha256-nPvD15JZmh0N5ce4QgnhwrLmAzbw8B4Z8FgWY5GHCPs="},"application-5eb87c6e13676d0183317debce17fade27e68c4acee28c419438da15d53c94f2.css":{"logical_path":"application.css","mtime":"2019-09-11T16:20:07+08:00","size":1844002,"digest":"5eb87c6e13676d0183317debce17fade27e68c4acee28c419438da15d53c94f2","integrity":"sha256-Xrh8bhNnbQGDMX3rzhf63ifmjErO4oxBlDjaFdU8lPI="},"admin-c9e5ebe6191548550e27514196ea125cfbb402820ec125a0c9acf99d2d378fe4.js":{"logical_path":"admin.js","mtime":"2019-09-21T15:28:08+08:00","size":4382031,"digest":"c9e5ebe6191548550e27514196ea125cfbb402820ec125a0c9acf99d2d378fe4","integrity":"sha256-yeXr5hkVSFUOJ1FBluoSXPu0AoIOwSWgyaz5nS03j+Q="},"admin-59c59f8cae8bef4a8359286c985458110c9d03ea121516595c988943f4717c38.css":{"logical_path":"admin.css","mtime":"2019-09-21T14:49:04+08:00","size":840093,"digest":"59c59f8cae8bef4a8359286c985458110c9d03ea121516595c988943f4717c38","integrity":"sha256-WcWfjK6L70qDWShsmFRYEQydA+oSFRZZXJiJQ/RxfDg="},"college-38f953d6ba5b85d3fab63cb3c2bbf0d057ccc6454d07cfaafac3b06da37b8437.css":{"logical_path":"college.css","mtime":"2019-09-16T13:56:09+08:00","size":579109,"digest":"38f953d6ba5b85d3fab63cb3c2bbf0d057ccc6454d07cfaafac3b06da37b8437","integrity":"sha256-OPlT1rpbhdP6tjyzwrvw0FfMxkVNB8+q+sOwbaN7hDc="},"application-646b1158a4e8c1f13e684d6fe9025abc75f8d3ba5256e440802c0398223374f3.css":{"logical_path":"application.css","mtime":"2019-09-21T14:49:04+08:00","size":1988767,"digest":"646b1158a4e8c1f13e684d6fe9025abc75f8d3ba5256e440802c0398223374f3","integrity":"sha256-ZGsRWKTowfE+aE1v6QJavHX407pSVuRAgCwDmCIzdPM="},"admin-a47e37c0ec7cf5f22380249776d1e82d65b6b6aa272ed7389185aa200fa40751.js":{"logical_path":"admin.js","mtime":"2019-09-25T15:33:05+08:00","size":4383107,"digest":"a47e37c0ec7cf5f22380249776d1e82d65b6b6aa272ed7389185aa200fa40751","integrity":"sha256-pH43wOx89fIjgCSXdtHoLWW2tqonLtc4kYWqIA+kB1E="},"admin-432c4eac09b036c57ff1e88d902b8aa7df81164e4b419bac557cf1366c1d3ad9.js":{"logical_path":"admin.js","mtime":"2019-09-25T15:35:20+08:00","size":4383103,"digest":"432c4eac09b036c57ff1e88d902b8aa7df81164e4b419bac557cf1366c1d3ad9","integrity":"sha256-QyxOrAmwNsV/8eiNkCuKp9+BFk5LQZusVXzxNmwdOtk="},"admin-978e5ce607f77c26814a174f480da79ac246c2201868ef84654aa03bb6727b5a.js":{"logical_path":"admin.js","mtime":"2019-09-30T14:43:41+08:00","size":4387200,"digest":"978e5ce607f77c26814a174f480da79ac246c2201868ef84654aa03bb6727b5a","integrity":"sha256-l45c5gf3fCaBShdPSA2nmsJGwiAYaO+EZUqgO7Zye1o="},"admin-896281f4731722b0c084dbb1af21d0f34a5bc142d58aff57b391864ab71ddca7.css":{"logical_path":"admin.css","mtime":"2019-09-30T14:43:41+08:00","size":842269,"digest":"896281f4731722b0c084dbb1af21d0f34a5bc142d58aff57b391864ab71ddca7","integrity":"sha256-iWKB9HMXIrDAhNuxryHQ80pbwULViv9Xs5GGSrcd3Kc="},"application-97f313e9bb7d25476649f7d7215959cf421480fd0a3785d1956953bf94a1e8bd.css":{"logical_path":"application.css","mtime":"2019-09-30T14:43:41+08:00","size":1993118,"digest":"97f313e9bb7d25476649f7d7215959cf421480fd0a3785d1956953bf94a1e8bd","integrity":"sha256-l/MT6bt9JUdmSffXIVlZz0IUgP0KN4XRlWlTv5Sh6L0="},"admin-2cdb23442fa735025385b88f2900df04fef38b61530041a6dbe375ef0f0ae888.js":{"logical_path":"admin.js","mtime":"2019-10-11T14:38:33+08:00","size":4394616,"digest":"2cdb23442fa735025385b88f2900df04fef38b61530041a6dbe375ef0f0ae888","integrity":"sha256-LNsjRC+nNQJThbiPKQDfBP7zi2FTAEGm2+N17w8K6Ig="},"admin-2c2854b9a02158ded5a809aaf7144a8630b10354ab4e56fecc4dffcc713796cc.css":{"logical_path":"admin.css","mtime":"2019-10-10T17:12:05+08:00","size":846514,"digest":"2c2854b9a02158ded5a809aaf7144a8630b10354ab4e56fecc4dffcc713796cc","integrity":"sha256-LChUuaAhWN7VqAmq9xRKhjCxA1SrTlb+zE3/zHE3lsw="},"application-50059ae929866043b47015128702fcfba53d32a2df148e64e1d961c10651c6af.css":{"logical_path":"application.css","mtime":"2019-10-10T17:12:05+08:00","size":2001607,"digest":"50059ae929866043b47015128702fcfba53d32a2df148e64e1d961c10651c6af","integrity":"sha256-UAWa6SmGYEO0cBUShwL8+6U9MqLfFI5k4dlhwQZRxq8="},"admin-992cde09b6d17f00a49576ae2d9f1ced127244ba401ef5b7d677cab9741688d2.js":{"logical_path":"admin.js","mtime":"2019-10-16T16:11:32+08:00","size":4394790,"digest":"992cde09b6d17f00a49576ae2d9f1ced127244ba401ef5b7d677cab9741688d2","integrity":"sha256-mSzeCbbRfwCklXauLZ8c7RJyRLpAHvW31nfKuXQWiNI="},"admin-84f2a7791e275d6f820514370b3f968176b994b9dd7b8c3ba8bf48336b03f257.css":{"logical_path":"admin.css","mtime":"2019-10-16T19:25:40+08:00","size":846676,"digest":"84f2a7791e275d6f820514370b3f968176b994b9dd7b8c3ba8bf48336b03f257","integrity":"sha256-hPKneR4nXW+CBRQ3Cz+WgXa5lLnde4w7qL9IM2sD8lc="},"application-ef6bab84852baaf69a91fe6af875b6e1b118c55b4c7d165665c488fac80c4997.css":{"logical_path":"application.css","mtime":"2019-10-16T19:25:40+08:00","size":2001931,"digest":"ef6bab84852baaf69a91fe6af875b6e1b118c55b4c7d165665c488fac80c4997","integrity":"sha256-72urhIUrqvaakf5q+HW24bEYxVtMfRZWZcSI+sgMSZc="},"admin-c99030d305662f740aa84b6c925a1adbbaadaa07fd74e2655e64d44b4b97fc4a.js":{"logical_path":"admin.js","mtime":"2019-10-17T09:44:58+08:00","size":4394897,"digest":"c99030d305662f740aa84b6c925a1adbbaadaa07fd74e2655e64d44b4b97fc4a","integrity":"sha256-yZAw0wVmL3QKqEtskloa27qtqgf9dOJlXmTUS0uX/Eo="},"admin-534bde871d67f4d6fc8da611917d78be4066fc7593ba53ee92aa17068a199d6d.css":{"logical_path":"admin.css","mtime":"2019-10-17T10:22:41+08:00","size":846699,"digest":"534bde871d67f4d6fc8da611917d78be4066fc7593ba53ee92aa17068a199d6d","integrity":"sha256-U0vehx1n9Nb8jaYRkX14vkBm/HWTulPukqoXBooZnW0="},"cooperative-04cd6a60d41220d38ee45ce40b1d004e1d0bcd87c132fb1a7bab6144c1deb8d7.js":{"logical_path":"cooperative.js","mtime":"2019-10-17T10:17:56+08:00","size":4330072,"digest":"04cd6a60d41220d38ee45ce40b1d004e1d0bcd87c132fb1a7bab6144c1deb8d7","integrity":"sha256-BM1qYNQSINOO5FzkCx0ATh0LzYfBMvsae6thRMHeuNc="},"cooperative-a345bbfd8e38b70c9285ecc1747012ffcde429187983e2aea5657abb56b9b4f3.css":{"logical_path":"cooperative.css","mtime":"2019-10-17T10:21:41+08:00","size":830628,"digest":"a345bbfd8e38b70c9285ecc1747012ffcde429187983e2aea5657abb56b9b4f3","integrity":"sha256-o0W7/Y44twyShezBdHAS/83kKRh5g+KupWV6u1a5tPM="},"application-0e417478d56f42467e857cd186b29cbbc0d6c7c6e85c8a6f42f39ac618943de8.css":{"logical_path":"application.css","mtime":"2019-09-03T08:55:53+08:00","size":442932,"digest":"0e417478d56f42467e857cd186b29cbbc0d6c7c6e85c8a6f42f39ac618943de8","integrity":"sha256-DkF0eNVvQkZ+hXzRhrKcu8DWx8boXIpvQvOaxhiUPeg="},"cooperative-149f47b8675d60a8014ccff50f00f932ff69e2be286ffb74343bc4a3effb135b.js":{"logical_path":"cooperative.js","mtime":"2019-10-17T14:03:03+08:00","size":4338033,"digest":"149f47b8675d60a8014ccff50f00f932ff69e2be286ffb74343bc4a3effb135b","integrity":"sha256-FJ9HuGddYKgBTM/1DwD5Mv9p4r4ob/t0NDvEo+/7E1s="},"cooperative-6273b766d6ef11dd56174d868bab55e7f17af17546c888d2ba0dd0a6bcda76c8.css":{"logical_path":"cooperative.css","mtime":"2019-10-17T11:13:07+08:00","size":832914,"digest":"6273b766d6ef11dd56174d868bab55e7f17af17546c888d2ba0dd0a6bcda76c8","integrity":"sha256-YnO3ZtbvEd1WF02Gi6tV5/F68XVGyIjSug3Qprzadsg="},"admin-82f66cc80b5649c6530a562567f28fe8d05f7bc3b8221e0695b2216255c52ba6.js":{"logical_path":"admin.js","mtime":"2019-10-21T13:51:43+08:00","size":4397012,"digest":"82f66cc80b5649c6530a562567f28fe8d05f7bc3b8221e0695b2216255c52ba6","integrity":"sha256-gvZsyAtWScZTClYlZ/KP6NBfe8O4Ih4GlbIhYlXFK6Y="},"admin-1b5728d94f6bccfbcef452a760d94c3b6f31966bc65d7f89be077fc2ea512bec.js":{"logical_path":"admin.js","mtime":"2019-10-21T16:41:06+08:00","size":4397437,"digest":"1b5728d94f6bccfbcef452a760d94c3b6f31966bc65d7f89be077fc2ea512bec","integrity":"sha256-G1co2U9rzPvO9FKnYNlMO28xlmvGXX+Jvgd/wupRK+w="},"admin-c8c127fefa5eca98bca19832c246619318164e8f242635c07033e2423cc18a6f.js":{"logical_path":"admin.js","mtime":"2019-10-22T09:53:29+08:00","size":4408150,"digest":"c8c127fefa5eca98bca19832c246619318164e8f242635c07033e2423cc18a6f","integrity":"sha256-yMEn/vpeypi8oZgywkZhkxgWTo8kJjXAcDPiQjzBim8="},"admin-60d200c1fcdf61a60537d29ccf4479c6b1e5e904208870a63b8ee677c96b347e.css":{"logical_path":"admin.css","mtime":"2019-10-22T09:43:20+08:00","size":851150,"digest":"60d200c1fcdf61a60537d29ccf4479c6b1e5e904208870a63b8ee677c96b347e","integrity":"sha256-YNIAwfzfYaYFN9Kcz0R5xrHl6QQgiHCmO47md8lrNH4="},"cooperative-9fb7ac4ad44081fafd5ad2a3a1bfb7f4329ac96f28bc6446d1ff52b1e2e71286.js":{"logical_path":"cooperative.js","mtime":"2019-10-22T09:55:26+08:00","size":4338142,"digest":"9fb7ac4ad44081fafd5ad2a3a1bfb7f4329ac96f28bc6446d1ff52b1e2e71286","integrity":"sha256-n7esStRAgfr9WtKjob+39DKayW8ovGRG0f9SseLnEoY="},"admin-a11066081d60365ddf25d5867560d1ccdd3197dbe82a5b6e969cc940e3429ff1.js":{"logical_path":"admin.js","mtime":"2019-10-24T14:16:30+08:00","size":4524252,"digest":"a11066081d60365ddf25d5867560d1ccdd3197dbe82a5b6e969cc940e3429ff1","integrity":"sha256-oRBmCB1gNl3fJdWGdWDRzN0xl9voKltulpzJQONCn/E="},"admin-7ce3dd717f7d12fcbc64caf14200230a1e68db439be0ba1879077599ff2c32c6.css":{"logical_path":"admin.css","mtime":"2019-10-24T10:10:08+08:00","size":852772,"digest":"7ce3dd717f7d12fcbc64caf14200230a1e68db439be0ba1879077599ff2c32c6","integrity":"sha256-fOPdcX99Evy8ZMrxQgAjCh5o20Ob4LoYeQd1mf8sMsY="},"college-93904c65d52c125aec0a463b9fd98bedda0018b78707f806be22685cca5d3747.css":{"logical_path":"college.css","mtime":"2019-10-24T10:10:08+08:00","size":579546,"digest":"93904c65d52c125aec0a463b9fd98bedda0018b78707f806be22685cca5d3747","integrity":"sha256-k5BMZdUsElrsCkY7n9mL7doAGLeHB/gGviJoXMpdN0c="},"cooperative-84c79d26a36aff5b496551b6d21b1bfb726b1bbc4153435a366115e96c204e06.js":{"logical_path":"cooperative.js","mtime":"2019-10-24T14:17:15+08:00","size":4338225,"digest":"84c79d26a36aff5b496551b6d21b1bfb726b1bbc4153435a366115e96c204e06","integrity":"sha256-hMedJqNq/1tJZVG20hsb+3JrG7xBU0NaNmEV6WwgTgY="},"cooperative-10a9ee5177e196572573ccea460e133c748072e223fdb473d05ee72c991fbbe3.css":{"logical_path":"cooperative.css","mtime":"2019-10-24T10:10:08+08:00","size":833351,"digest":"10a9ee5177e196572573ccea460e133c748072e223fdb473d05ee72c991fbbe3","integrity":"sha256-EKnuUXfhllclc8zqRg4TPHSAcuIj/bRz0F7nLJkfu+M="},"admin-441d8f3722e5f73e5748aaeb6f517101474cb1eb48a99f119e561f08b9e9dc60.js":{"logical_path":"admin.js","mtime":"2019-10-24T16:08:56+08:00","size":4525031,"digest":"441d8f3722e5f73e5748aaeb6f517101474cb1eb48a99f119e561f08b9e9dc60","integrity":"sha256-RB2PNyLl9z5XSKrrb1FxAUdMsetIqZ8RnlYfCLnp3GA="},"admin-76c52986591f274f639ad48dfbb480a1aeeec7647b6fa28fa541e78a064b6316.css":{"logical_path":"admin.css","mtime":"2019-10-24T15:25:17+08:00","size":867945,"digest":"76c52986591f274f639ad48dfbb480a1aeeec7647b6fa28fa541e78a064b6316","integrity":"sha256-dsUphlkfJ09jmtSN+7SAoa7ux2R7b6KPpUHnigZLYxY="},"cooperative-6c4c663b6b5071535bab2b76cc5e05ab5682665857763a76bf4f01afef51be5a.js":{"logical_path":"cooperative.js","mtime":"2019-10-24T17:56:20+08:00","size":4339039,"digest":"6c4c663b6b5071535bab2b76cc5e05ab5682665857763a76bf4f01afef51be5a","integrity":"sha256-bExmO2tQcVNbqyt2zF4Fq1aCZlhXdjp2v08Br+9Rvlo="},"admin-c63acadd431434979db50540a0bf7e65c75e1de0d1b449919f2cce89a0548d43.js":{"logical_path":"admin.js","mtime":"2019-10-24T18:12:33+08:00","size":4533182,"digest":"c63acadd431434979db50540a0bf7e65c75e1de0d1b449919f2cce89a0548d43","integrity":"sha256-xjrK3UMUNJedtQVAoL9+ZcdeHeDRtEmRnyzOiaBUjUM="},"admin-bd832b9a35eb3743dde9218beab61f9bcde1508767ad68dbedb1c89a4bb65c3a.css":{"logical_path":"admin.css","mtime":"2019-10-24T17:56:20+08:00","size":861450,"digest":"bd832b9a35eb3743dde9218beab61f9bcde1508767ad68dbedb1c89a4bb65c3a","integrity":"sha256-vYMrmjXrN0Pd6SGL6rYfm83hUIdnrWjb7bHImku2XDo="},"college-fa202780f3e7f96cb9b5916c6f0d7dd9e03cb746864bbd2dd491ed001c30ad8f.css":{"logical_path":"college.css","mtime":"2019-10-24T17:56:20+08:00","size":571936,"digest":"fa202780f3e7f96cb9b5916c6f0d7dd9e03cb746864bbd2dd491ed001c30ad8f","integrity":"sha256-+iAngPPn+Wy5tZFsbw192eA8t0aGS70t1JHtABwwrY8="},"cooperative-4f233e8963b0bd80bc56b71c209d31464d314240ac8d686806baf99511c53ad0.css":{"logical_path":"cooperative.css","mtime":"2019-10-24T17:56:20+08:00","size":825741,"digest":"4f233e8963b0bd80bc56b71c209d31464d314240ac8d686806baf99511c53ad0","integrity":"sha256-TyM+iWOwvYC8VrccIJ0xRk0xQkCsjWhoBrr5lRHFOtA="},"application-8c9d6bb61c50908f584b3070c79aeb95f25c1166d39e07da5e95438b39ca0de9.css":{"logical_path":"application.css","mtime":"2019-10-21T22:52:15+08:00","size":436995,"digest":"8c9d6bb61c50908f584b3070c79aeb95f25c1166d39e07da5e95438b39ca0de9","integrity":"sha256-jJ1rthxQkI9YSzBwx5rrlfJcEWbTngfaXpVDiznKDek="},"admin-bf2bd889f02d15c4913aa260497d72afeb26d701aac49a4ef6a75619af030152.js":{"logical_path":"admin.js","mtime":"2019-10-25T10:12:17+08:00","size":4533673,"digest":"bf2bd889f02d15c4913aa260497d72afeb26d701aac49a4ef6a75619af030152","integrity":"sha256-vyvYifAtFcSROqJgSX1yr+sm1wGqxJpO9qdWGa8DAVI="},"admin-46e564d29ffae5c71ae9b5e36dc0bd5de57b10f396eb2005bfb9cf51e7744cdd.css":{"logical_path":"admin.css","mtime":"2019-10-25T10:12:17+08:00","size":870355,"digest":"46e564d29ffae5c71ae9b5e36dc0bd5de57b10f396eb2005bfb9cf51e7744cdd","integrity":"sha256-RuVk0p/65cca6bXjbcC9XeV7EPOW6yAFv7nPUed0TN0="},"college-2299e05f5e9b640e333ece624d4ab18a678fdabff0bc18b69a9c2e3de49cba8e.css":{"logical_path":"college.css","mtime":"2019-10-25T10:12:17+08:00","size":580077,"digest":"2299e05f5e9b640e333ece624d4ab18a678fdabff0bc18b69a9c2e3de49cba8e","integrity":"sha256-IpngX16bZA4zPs5iTUqximeP2r/wvBi2mpwuPeScuo4="},"cooperative-f1ac8f14ad6ade8d1f79ca49ea9c79be77d49aae9d2705ca672e78444481700d.js":{"logical_path":"cooperative.js","mtime":"2019-10-25T11:01:38+08:00","size":4409145,"digest":"f1ac8f14ad6ade8d1f79ca49ea9c79be77d49aae9d2705ca672e78444481700d","integrity":"sha256-8ayPFK1q3o0fecpJ6px5vnfUmq6dJwXKZy54RESBcA0="},"cooperative-8057adee2454dbc9d648305faf9ede9824f40d3bd0184e816e8035bb7f1e730b.css":{"logical_path":"cooperative.css","mtime":"2019-10-25T10:12:17+08:00","size":833882,"digest":"8057adee2454dbc9d648305faf9ede9824f40d3bd0184e816e8035bb7f1e730b","integrity":"sha256-gFet7iRU28nWSDBfr57emCT0DTvQGE6BboA1u38ecws="},"admin-6f9bb9720e7e5040ae559a8fae11553313f77552a76416b3a9fe77198471964d.js":{"logical_path":"admin.js","mtime":"2019-10-25T17:00:09+08:00","size":4554537,"digest":"6f9bb9720e7e5040ae559a8fae11553313f77552a76416b3a9fe77198471964d","integrity":"sha256-b5u5cg5+UECuVZqPrhFVMxP3dVKnZBazqf53GYRxlk0="},"admin-ab3e0f7240ae4df8d1585c8d5e99df41edd3305ecc2abadcf8820796e1d9fc65.css":{"logical_path":"admin.css","mtime":"2019-10-25T09:55:22+08:00","size":862288,"digest":"ab3e0f7240ae4df8d1585c8d5e99df41edd3305ecc2abadcf8820796e1d9fc65","integrity":"sha256-qz4PckCuTfjRWFyNXpnfQe3TMF7MKrrc+IIHluHZ/GU="},"college-2fdfc5431b46ad4a454a25386dbcbc390466886f76b85fdb7e3f75018196a870.css":{"logical_path":"college.css","mtime":"2019-10-25T09:55:22+08:00","size":572010,"digest":"2fdfc5431b46ad4a454a25386dbcbc390466886f76b85fdb7e3f75018196a870","integrity":"sha256-L9/FQxtGrUpFSiU4bby8OQRmiG92uF/bfj91AYGWqHA="},"cooperative-47d516a0904d0633e82c1de39a6ec4c9e6de0a37813843e01d4bacf97e8b2ebf.css":{"logical_path":"cooperative.css","mtime":"2019-10-25T09:55:22+08:00","size":825815,"digest":"47d516a0904d0633e82c1de39a6ec4c9e6de0a37813843e01d4bacf97e8b2ebf","integrity":"sha256-R9UWoJBNBjPoLB3jmm7EyebeCjeBOEPgHUus+X6LLr8="},"admin-839af7c0d2917a8f8019d0376ea17cec050ef4d19d98c6c10de91f5d2bc81adf.js":{"logical_path":"admin.js","mtime":"2019-10-26T11:25:08+08:00","size":4554543,"digest":"839af7c0d2917a8f8019d0376ea17cec050ef4d19d98c6c10de91f5d2bc81adf","integrity":"sha256-g5r3wNKReo+AGdA3bqF87AUO9NGdmMbBDekfXSvIGt8="},"admin-52d692608c620ae47717a2ac88377e55b9b58af0acdf3f777814a1fd47b6594b.js":{"logical_path":"admin.js","mtime":"2019-10-26T17:16:18+08:00","size":4553202,"digest":"52d692608c620ae47717a2ac88377e55b9b58af0acdf3f777814a1fd47b6594b","integrity":"sha256-UtaSYIxiCuR3F6KsiDd+Vbm1ivCs3z93eBSh/Ue2WUs="},"admin-b58555ae641bbaa61e3af0ddd2756acc3c5de9023c737815c72132cc67c9a403.js":{"logical_path":"admin.js","mtime":"2019-10-27T13:06:02+08:00","size":4553607,"digest":"b58555ae641bbaa61e3af0ddd2756acc3c5de9023c737815c72132cc67c9a403","integrity":"sha256-tYVVrmQbuqYeOvDd0nVqzDxd6QI8c3gVxyEyzGfJpAM="},"admin-b95c48ea51f392ce7c4024d0d8b2c42dfe48528a1898ec3f7818e0cda2a4f224.js":{"logical_path":"admin.js","mtime":"2019-10-28T10:46:29+08:00","size":4554008,"digest":"b95c48ea51f392ce7c4024d0d8b2c42dfe48528a1898ec3f7818e0cda2a4f224","integrity":"sha256-uVxI6lHzks58QCTQ2LLELf5IUooYmOw/eBjgzaKk8iQ="},"admin-1f2e5a2a28462df8bcddfbdbfbebdc36a761ca7a94962ae71d37fb8c06fc5f94.js":{"logical_path":"admin.js","mtime":"2019-10-29T08:57:11+08:00","size":4554938,"digest":"1f2e5a2a28462df8bcddfbdbfbebdc36a761ca7a94962ae71d37fb8c06fc5f94","integrity":"sha256-Hy5aKihGLfi83fvb++vcNqdhynqUlirnHTf7jAb8X5Q="},"admin-cb3d4541758ef2bcbfe16f518d48f85097d0547a587de222d2fc13dbdd474b4b.js":{"logical_path":"admin.js","mtime":"2019-10-29T14:06:13+08:00","size":4556541,"digest":"cb3d4541758ef2bcbfe16f518d48f85097d0547a587de222d2fc13dbdd474b4b","integrity":"sha256-yz1FQXWO8ry/4W9RjUj4UJfQVHpYfeIi0vwT291HS0s="},"admin-6a76c25b6691b4f436608be28606d90c907ba8f033f5f47c6c20d7bf11251cb6.css":{"logical_path":"admin.css","mtime":"2019-10-29T14:22:47+08:00","size":871031,"digest":"6a76c25b6691b4f436608be28606d90c907ba8f033f5f47c6c20d7bf11251cb6","integrity":"sha256-anbCW2aRtPQ2YIvihgbZDJB7qPAz9fR8bCDXvxElHLY="},"admin-ba909dfe0de4d216bedb3c743144321e4023837568abab1d3ee9a28b2faa5925.js":{"logical_path":"admin.js","mtime":"2019-10-29T14:43:01+08:00","size":4556622,"digest":"ba909dfe0de4d216bedb3c743144321e4023837568abab1d3ee9a28b2faa5925","integrity":"sha256-upCd/g3k0ha+2zx0MUQyHkAjg3Voq6sdPumiiy+qWSU="},"admin-e975e2039206e9ae2b6a072fee083cf39b8e04f2318f67bfbf1923fe208456b3.js":{"logical_path":"admin.js","mtime":"2019-10-29T15:50:27+08:00","size":4559454,"digest":"e975e2039206e9ae2b6a072fee083cf39b8e04f2318f67bfbf1923fe208456b3","integrity":"sha256-6XXiA5IG6a4ragcv7gg885uOBPIxj2e/vxkj/iCEVrM="},"cooperative-a309d245cd0b0b9c653db471c53ec090e49ba7ad885879ffa02a11b6efd79d74.js":{"logical_path":"cooperative.js","mtime":"2019-10-29T15:50:27+08:00","size":4409163,"digest":"a309d245cd0b0b9c653db471c53ec090e49ba7ad885879ffa02a11b6efd79d74","integrity":"sha256-ownSRc0LC5xlPbRxxT7AkOSbp62IWHn/oCoRtu/XnXQ="},"admin-5d791c4f4a14e1586cfa44776ae262b3c1494e1c0fb0e00c330f0cb9d30fd7ba.js":{"logical_path":"admin.js","mtime":"2019-11-01T08:41:10+08:00","size":4563272,"digest":"5d791c4f4a14e1586cfa44776ae262b3c1494e1c0fb0e00c330f0cb9d30fd7ba","integrity":"sha256-XXkcT0oU4Vhs+kR3auJis8FJThwPsOAMMw8MudMP17o="},"admin-70dc0e7136a8f54139e4167c00f3fde9ccc92b404b01b37ac6064913806e3f6e.css":{"logical_path":"admin.css","mtime":"2019-10-31T10:05:33+08:00","size":872438,"digest":"70dc0e7136a8f54139e4167c00f3fde9ccc92b404b01b37ac6064913806e3f6e","integrity":"sha256-cNwOcTao9UE55BZ8APP96czJK0BLAbN6xgZJE4BuP24="},"cooperative-4fe879591997da39d38e94f6f5eb3b688aa827fa42cb8fd73d21bc96ed880236.js":{"logical_path":"cooperative.js","mtime":"2019-11-01T08:41:10+08:00","size":4409560,"digest":"4fe879591997da39d38e94f6f5eb3b688aa827fa42cb8fd73d21bc96ed880236","integrity":"sha256-T+h5WRmX2jnTjpT29es7aIqoJ/pCy4/XPSG8lu2IAjY="}},"assets":{"admin.js":"admin-5d791c4f4a14e1586cfa44776ae262b3c1494e1c0fb0e00c330f0cb9d30fd7ba.js","admin.css":"admin-70dc0e7136a8f54139e4167c00f3fde9ccc92b404b01b37ac6064913806e3f6e.css","font-awesome/fontawesome-webfont.eot":"font-awesome/fontawesome-webfont-7bfcab6db99d5cfbf1705ca0536ddc78585432cc5fa41bbd7ad0f009033b2979.eot","font-awesome/fontawesome-webfont.woff2":"font-awesome/fontawesome-webfont-2adefcbc041e7d18fcf2d417879dc5a09997aa64d675b7a3c4b6ce33da13f3fe.woff2","font-awesome/fontawesome-webfont.woff":"font-awesome/fontawesome-webfont-ba0c59deb5450f5cb41b3f93609ee2d0d995415877ddfa223e8a8a7533474f07.woff","font-awesome/fontawesome-webfont.ttf":"font-awesome/fontawesome-webfont-aa58f33f239a0fb02f5c7a6c45c043d7a9ac9a093335806694ecd6d4edc0d6a8.ttf","font-awesome/fontawesome-webfont.svg":"font-awesome/fontawesome-webfont-ad6157926c1622ba4e1d03d478f1541368524bfc46f51e42fe0d945f7ef323e4.svg","college.js":"college-18f5e8400331634e898a35acc2187815c096c25e0ab74aba341ae916166cd287.js","college.css":"college-2299e05f5e9b640e333ece624d4ab18a678fdabff0bc18b69a9c2e3de49cba8e.css","logo.png":"logo-7ff112568709bf97f9898fe87249b7a8f200ff1f48d537d85af87215f1870423.png","application.js":"application-9cfbc3d792599a1d0de5c7b84209e1c2b2e60336f0f01e19f0581663918708fb.js","application.css":"application-0e417478d56f42467e857cd186b29cbbc0d6c7c6e85c8a6f42f39ac618943de8.css","cooperative.js":"cooperative-4fe879591997da39d38e94f6f5eb3b688aa827fa42cb8fd73d21bc96ed880236.js","cooperative.css":"cooperative-8057adee2454dbc9d648305faf9ede9824f40d3bd0184e816e8035bb7f1e730b.css"}} \ No newline at end of file diff --git a/public/assets/admin-e975e2039206e9ae2b6a072fee083cf39b8e04f2318f67bfbf1923fe208456b3.js b/public/assets/admin-5d791c4f4a14e1586cfa44776ae262b3c1494e1c0fb0e00c330f0cb9d30fd7ba.js similarity index 99% rename from public/assets/admin-e975e2039206e9ae2b6a072fee083cf39b8e04f2318f67bfbf1923fe208456b3.js rename to public/assets/admin-5d791c4f4a14e1586cfa44776ae262b3c1494e1c0fb0e00c330f0cb9d30fd7ba.js index 99f6c6ade..3cbff295d 100644 --- a/public/assets/admin-e975e2039206e9ae2b6a072fee083cf39b8e04f2318f67bfbf1923fe208456b3.js +++ b/public/assets/admin-5d791c4f4a14e1586cfa44776ae262b3c1494e1c0fb0e00c330f0cb9d30fd7ba.js @@ -18871,7 +18871,7 @@ return Popper; * Copyright (c) 2019 Jörn Zaefferer; Licensed MIT */ !function(a){"function"==typeof define&&define.amd?define(["jquery","./jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return function(){function b(a){return a.replace(/<.[^<>]*?>/g," ").replace(/ | /gi," ").replace(/[.(),;:!?%#$'\"_+=\/\-“”’]*/g,"")}a.validator.addMethod("maxWords",function(a,c,d){return this.optional(c)||b(a).match(/\b\w+\b/g).length<=d},a.validator.format("Please enter {0} words or less.")),a.validator.addMethod("minWords",function(a,c,d){return this.optional(c)||b(a).match(/\b\w+\b/g).length>=d},a.validator.format("Please enter at least {0} words.")),a.validator.addMethod("rangeWords",function(a,c,d){var e=b(a),f=/\b\w+\b/g;return this.optional(c)||e.match(f).length>=d[0]&&e.match(f).length<=d[1]},a.validator.format("Please enter between {0} and {1} words."))}(),a.validator.addMethod("abaRoutingNumber",function(a){var b=0,c=a.split(""),d=c.length;if(9!==d)return!1;for(var e=0;e9?"0":f,g="JABCDEFGHI".substr(f,1).toString(),i.match(/[ABEH]/)?k===f:i.match(/[KPQS]/)?k===g:k===f||k===g},"Please specify a valid CIF number."),a.validator.addMethod("cnhBR",function(a){if(a=a.replace(/([~!@#$%^&*()_+=`{}\[\]\-|\\:;'<>,.\/? ])+/g,""),11!==a.length)return!1;var b,c,d,e,f,g,h=0,i=0;if(b=a.charAt(0),new Array(12).join(b)===a)return!1;for(e=0,f=9,g=0;e<9;++e,--f)h+=+(a.charAt(e)*f);for(c=h%11,c>=10&&(c=0,i=2),h=0,e=0,f=1,g=0;e<9;++e,++f)h+=+(a.charAt(e)*f);return d=h%11,d>=10?d=0:d-=i,String(c).concat(d)===a.substr(-2)},"Please specify a valid CNH number"),a.validator.addMethod("cnpjBR",function(a,b){"use strict";if(this.optional(b))return!0;if(a=a.replace(/[^\d]+/g,""),14!==a.length)return!1;if("00000000000000"===a||"11111111111111"===a||"22222222222222"===a||"33333333333333"===a||"44444444444444"===a||"55555555555555"===a||"66666666666666"===a||"77777777777777"===a||"88888888888888"===a||"99999999999999"===a)return!1;for(var c=a.length-2,d=a.substring(0,c),e=a.substring(c),f=0,g=c-7,h=c;h>=1;h--)f+=d.charAt(c-h)*g--,g<2&&(g=9);var i=f%11<2?0:11-f%11;if(i!==parseInt(e.charAt(0),10))return!1;c+=1,d=a.substring(0,c),f=0,g=c-7;for(var j=c;j>=1;j--)f+=d.charAt(c-j)*g--,g<2&&(g=9);return i=f%11<2?0:11-f%11,i===parseInt(e.charAt(1),10)},"Please specify a CNPJ value number"),a.validator.addMethod("cpfBR",function(a,b){"use strict";if(this.optional(b))return!0;if(a=a.replace(/([~!@#$%^&*()_+=`{}\[\]\-|\\:;'<>,.\/? ])+/g,""),11!==a.length)return!1;var c,d,e,f,g=0;if(c=parseInt(a.substring(9,10),10),d=parseInt(a.substring(10,11),10),e=function(a,b){var c=10*a%11;return 10!==c&&11!==c||(c=0),c===b},""===a||"00000000000"===a||"11111111111"===a||"22222222222"===a||"33333333333"===a||"44444444444"===a||"55555555555"===a||"66666666666"===a||"77777777777"===a||"88888888888"===a||"99999999999"===a)return!1;for(f=1;f<=9;f++)g+=parseInt(a.substring(f-1,f),10)*(11-f);if(e(g,c)){for(g=0,f=1;f<=10;f++)g+=parseInt(a.substring(f-1,f),10)*(12-f);return e(g,d)}return!1},"Please specify a valid CPF number"),a.validator.addMethod("creditcard",function(a,b){if(this.optional(b))return"dependency-mismatch";if(/[^0-9 \-]+/.test(a))return!1;var c,d,e=0,f=0,g=!1;if(a=a.replace(/\D/g,""),a.length<13||a.length>19)return!1;for(c=a.length-1;c>=0;c--)d=a.charAt(c),f=parseInt(d,10),g&&(f*=2)>9&&(f-=9),e+=f,g=!g;return e%10===0},"Please enter a valid credit card number."),a.validator.addMethod("creditcardtypes",function(a,b,c){if(/[^0-9\-]+/.test(a))return!1;a=a.replace(/\D/g,"");var d=0;return c.mastercard&&(d|=1),c.visa&&(d|=2),c.amex&&(d|=4),c.dinersclub&&(d|=8),c.enroute&&(d|=16),c.discover&&(d|=32),c.jcb&&(d|=64),c.unknown&&(d|=128),c.all&&(d=255),1&d&&(/^(5[12345])/.test(a)||/^(2[234567])/.test(a))?16===a.length:2&d&&/^(4)/.test(a)?16===a.length:4&d&&/^(3[47])/.test(a)?15===a.length:8&d&&/^(3(0[012345]|[68]))/.test(a)?14===a.length:16&d&&/^(2(014|149))/.test(a)?15===a.length:32&d&&/^(6011)/.test(a)?16===a.length:64&d&&/^(3)/.test(a)?16===a.length:64&d&&/^(2131|1800)/.test(a)?15===a.length:!!(128&d)},"Please enter a valid credit card number."),a.validator.addMethod("currency",function(a,b,c){var d,e="string"==typeof c,f=e?c:c[0],g=!!e||c[1];return f=f.replace(/,/g,""),f=g?f+"]":f+"]?",d="^["+f+"([1-9]{1}[0-9]{0,2}(\\,[0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,}(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)$",d=new RegExp(d),this.optional(b)||d.test(a)},"Please specify a valid currency"),a.validator.addMethod("dateFA",function(a,b){return this.optional(b)||/^[1-4]\d{3}\/((0?[1-6]\/((3[0-1])|([1-2][0-9])|(0?[1-9])))|((1[0-2]|(0?[7-9]))\/(30|([1-2][0-9])|(0?[1-9]))))$/.test(a)},a.validator.messages.date),a.validator.addMethod("dateITA",function(a,b){var c,d,e,f,g,h=!1,i=/^\d{1,2}\/\d{1,2}\/\d{4}$/;return i.test(a)?(c=a.split("/"),d=parseInt(c[0],10),e=parseInt(c[1],10),f=parseInt(c[2],10),g=new Date(Date.UTC(f,e-1,d,12,0,0,0)),h=g.getUTCFullYear()===f&&g.getUTCMonth()===e-1&&g.getUTCDate()===d):h=!1,this.optional(b)||h},a.validator.messages.date),a.validator.addMethod("dateNL",function(a,b){return this.optional(b)||/^(0?[1-9]|[12]\d|3[01])[\.\/\-](0?[1-9]|1[012])[\.\/\-]([12]\d)?(\d\d)$/.test(a)},a.validator.messages.date),a.validator.addMethod("extension",function(a,b,c){return c="string"==typeof c?c.replace(/,/g,"|"):"png|jpe?g|gif",this.optional(b)||a.match(new RegExp("\\.("+c+")$","i"))},a.validator.format("Please enter a value with a valid extension.")),a.validator.addMethod("giroaccountNL",function(a,b){return this.optional(b)||/^[0-9]{1,7}$/.test(a)},"Please specify a valid giro account number"),a.validator.addMethod("greaterThan",function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.not(".validate-greaterThan-blur").length&&e.addClass("validate-greaterThan-blur").on("blur.validate-greaterThan",function(){a(c).valid()}),b>e.val()},"Please enter a greater value."),a.validator.addMethod("greaterThanEqual",function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.not(".validate-greaterThanEqual-blur").length&&e.addClass("validate-greaterThanEqual-blur").on("blur.validate-greaterThanEqual",function(){a(c).valid()}),b>=e.val()},"Please enter a greater value."),a.validator.addMethod("iban",function(a,b){if(this.optional(b))return!0;var c,d,e,f,g,h,i,j,k,l=a.replace(/ /g,"").toUpperCase(),m="",n=!0,o="",p="",q=5;if(l.lengthd)},a.validator.format("Please select no more than {0} files.")),a.validator.addMethod("maxsize",function(b,c,d){if(this.optional(c))return!0;if("file"===a(c).attr("type")&&c.files&&c.files.length)for(var e=0;ed)return!1;return!0},a.validator.format("File size must not exceed {0} bytes each.")),a.validator.addMethod("maxsizetotal",function(b,c,d){if(this.optional(c))return!0;if("file"===a(c).attr("type")&&c.files&&c.files.length)for(var e=0,f=0;fd)return!1;return!0},a.validator.format("Total size of all files must not exceed {0} bytes.")),a.validator.addMethod("mobileNL",function(a,b){return this.optional(b)||/^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)6((\s|\s?\-\s?)?[0-9]){8}$/.test(a)},"Please specify a valid mobile number"),a.validator.addMethod("mobileRU",function(a,b){var c=a.replace(/\(|\)|\s+|-/g,"");return this.optional(b)||c.length>9&&/^((\+7|7|8)+([0-9]){10})$/.test(c)},"Please specify a valid mobile number"),a.validator.addMethod("mobileUK",function(a,b){return a=a.replace(/\(|\)|\s+|-/g,""),this.optional(b)||a.length>9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?|0)7(?:[1345789]\d{2}|624)\s?\d{3}\s?\d{3})$/)},"Please specify a valid mobile number"),a.validator.addMethod("netmask",function(a,b){return this.optional(b)||/^(254|252|248|240|224|192|128)\.0\.0\.0|255\.(254|252|248|240|224|192|128|0)\.0\.0|255\.255\.(254|252|248|240|224|192|128|0)\.0|255\.255\.255\.(254|252|248|240|224|192|128|0)/i.test(a)},"Please enter a valid netmask."),a.validator.addMethod("nieES",function(a,b){"use strict";if(this.optional(b))return!0;var c,d=new RegExp(/^[MXYZ]{1}[0-9]{7,8}[TRWAGMYFPDXBNJZSQVHLCKET]{1}$/gi),e="TRWAGMYFPDXBNJZSQVHLCKET",f=a.substr(a.length-1).toUpperCase();return a=a.toString().toUpperCase(),!(a.length>10||a.length<9||!d.test(a))&&(a=a.replace(/^[X]/,"0").replace(/^[Y]/,"1").replace(/^[Z]/,"2"),c=9===a.length?a.substr(0,8):a.substr(0,9),e.charAt(parseInt(c,10)%23)===f)},"Please specify a valid NIE number."),a.validator.addMethod("nifES",function(a,b){"use strict";return!!this.optional(b)||(a=a.toUpperCase(),!!a.match("((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)")&&(/^[0-9]{8}[A-Z]{1}$/.test(a)?"TRWAGMYFPDXBNJZSQVHLCKE".charAt(a.substring(8,0)%23)===a.charAt(8):!!/^[KLM]{1}/.test(a)&&a[8]==="TRWAGMYFPDXBNJZSQVHLCKE".charAt(a.substring(8,1)%23)))},"Please specify a valid NIF number."),a.validator.addMethod("nipPL",function(a){"use strict";if(a=a.replace(/[^0-9]/g,""),10!==a.length)return!1;for(var b=[6,5,7,2,3,4,5,6,7],c=0,d=0;d<9;d++)c+=b[d]*a[d];var e=c%11,f=10===e?0:e;return f===parseInt(a[9],10)},"Please specify a valid NIP number."),a.validator.addMethod("nisBR",function(a){var b,c,d,e,f,g=0;if(a=a.replace(/([~!@#$%^&*()_+=`{}\[\]\-|\\:;'<>,.\/? ])+/g,""),11!==a.length)return!1;for(c=parseInt(a.substring(10,11),10),b=parseInt(a.substring(0,10),10),e=2;e<12;e++)f=e,10===e&&(f=2),11===e&&(f=3),g+=b%10*f,b=parseInt(b/10,10);return d=g%11,d=d>1?11-d:0,c===d},"Please specify a valid NIS/PIS number"),a.validator.addMethod("notEqualTo",function(b,c,d){return this.optional(c)||!a.validator.methods.equalTo.call(this,b,c,d)},"Please enter a different value, values must not be the same."),a.validator.addMethod("nowhitespace",function(a,b){return this.optional(b)||/^\S+$/i.test(a)},"No white space please"),a.validator.addMethod("pattern",function(a,b,c){return!!this.optional(b)||("string"==typeof c&&(c=new RegExp("^(?:"+c+")$")),c.test(a))},"Invalid format."),a.validator.addMethod("phoneNL",function(a,b){return this.optional(b)||/^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)[1-9]((\s|\s?\-\s?)?[0-9]){8}$/.test(a)},"Please specify a valid phone number."),a.validator.addMethod("phonePL",function(a,b){a=a.replace(/\s+/g,"");var c=/^(?:(?:(?:\+|00)?48)|(?:\(\+?48\)))?(?:1[2-8]|2[2-69]|3[2-49]|4[1-68]|5[0-9]|6[0-35-9]|[7-8][1-9]|9[145])\d{7}$/;return this.optional(b)||c.test(a)},"Please specify a valid phone number"),a.validator.addMethod("phonesUK",function(a,b){return a=a.replace(/\(|\)|\s+|-/g,""),this.optional(b)||a.length>9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?|0)(?:1\d{8,9}|[23]\d{9}|7(?:[1345789]\d{8}|624\d{6})))$/)},"Please specify a valid uk phone number"),a.validator.addMethod("phoneUK",function(a,b){return a=a.replace(/\(|\)|\s+|-/g,""),this.optional(b)||a.length>9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?)|(?:\(?0))(?:\d{2}\)?\s?\d{4}\s?\d{4}|\d{3}\)?\s?\d{3}\s?\d{3,4}|\d{4}\)?\s?(?:\d{5}|\d{3}\s?\d{3})|\d{5}\)?\s?\d{4,5})$/)},"Please specify a valid phone number"),a.validator.addMethod("phoneUS",function(a,b){return a=a.replace(/\s+/g,""),this.optional(b)||a.length>9&&a.match(/^(\+?1-?)?(\([2-9]([02-9]\d|1[02-9])\)|[2-9]([02-9]\d|1[02-9]))-?[2-9]\d{2}-?\d{4}$/)},"Please specify a valid phone number"),a.validator.addMethod("postalcodeBR",function(a,b){return this.optional(b)||/^\d{2}.\d{3}-\d{3}?$|^\d{5}-?\d{3}?$/.test(a)},"Informe um CEP válido."),a.validator.addMethod("postalCodeCA",function(a,b){return this.optional(b)||/^[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ] *\d[ABCEGHJKLMNPRSTVWXYZ]\d$/i.test(a)},"Please specify a valid postal code"),a.validator.addMethod("postalcodeIT",function(a,b){return this.optional(b)||/^\d{5}$/.test(a)},"Please specify a valid postal code"),a.validator.addMethod("postalcodeNL",function(a,b){return this.optional(b)||/^[1-9][0-9]{3}\s?[a-zA-Z]{2}$/.test(a)},"Please specify a valid postal code"),a.validator.addMethod("postcodeUK",function(a,b){return this.optional(b)||/^((([A-PR-UWYZ][0-9])|([A-PR-UWYZ][0-9][0-9])|([A-PR-UWYZ][A-HK-Y][0-9])|([A-PR-UWYZ][A-HK-Y][0-9][0-9])|([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))\s?([0-9][ABD-HJLNP-UW-Z]{2})|(GIR)\s?(0AA))$/i.test(a)},"Please specify a valid UK postcode"),a.validator.addMethod("require_from_group",function(b,c,d){var e=a(d[1],c.form),f=e.eq(0),g=f.data("valid_req_grp")?f.data("valid_req_grp"):a.extend({},this),h=e.filter(function(){return g.elementValue(this)}).length>=d[0];return f.data("valid_req_grp",g),a(c).data("being_validated")||(e.data("being_validated",!0),e.each(function(){g.element(this)}),e.data("being_validated",!1)),h},a.validator.format("Please fill at least {0} of these fields.")),a.validator.addMethod("skip_or_fill_minimum",function(b,c,d){var e=a(d[1],c.form),f=e.eq(0),g=f.data("valid_skip")?f.data("valid_skip"):a.extend({},this),h=e.filter(function(){return g.elementValue(this)}).length,i=0===h||h>=d[0];return f.data("valid_skip",g),a(c).data("being_validated")||(e.data("being_validated",!0),e.each(function(){g.element(this)}),e.data("being_validated",!1)),i},a.validator.format("Please either skip these fields or fill at least {0} of them.")),a.validator.addMethod("stateUS",function(a,b,c){var d,e="undefined"==typeof c,f=!e&&"undefined"!=typeof c.caseSensitive&&c.caseSensitive,g=!e&&"undefined"!=typeof c.includeTerritories&&c.includeTerritories,h=!e&&"undefined"!=typeof c.includeMilitary&&c.includeMilitary;return d=g||h?g&&h?"^(A[AEKLPRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$":g?"^(A[KLRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$":"^(A[AEKLPRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$":"^(A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$",d=f?new RegExp(d):new RegExp(d,"i"),this.optional(b)||d.test(a)},"Please specify a valid state"),a.validator.addMethod("strippedminlength",function(b,c,d){return a(b).text().length>=d},a.validator.format("Please enter at least {0} characters")),a.validator.addMethod("time",function(a,b){return this.optional(b)||/^([01]\d|2[0-3]|[0-9])(:[0-5]\d){1,2}$/.test(a)},"Please enter a valid time, between 00:00 and 23:59"),a.validator.addMethod("time12h",function(a,b){return this.optional(b)||/^((0?[1-9]|1[012])(:[0-5]\d){1,2}(\ ?[AP]M))$/i.test(a)},"Please enter a valid time in 12-hour am/pm format"),a.validator.addMethod("url2",function(a,b){return this.optional(b)||/^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(a)},a.validator.messages.url),a.validator.addMethod("vinUS",function(a){if(17!==a.length)return!1;var b,c,d,e,f,g,h=["A","B","C","D","E","F","G","H","J","K","L","M","N","P","R","S","T","U","V","W","X","Y","Z"],i=[1,2,3,4,5,6,7,8,1,2,3,4,5,7,9,2,3,4,5,6,7,8,9],j=[8,7,6,5,4,3,2,10,0,9,8,7,6,5,4,3,2],k=0;for(b=0;b<17;b++){if(e=j[b],d=a.slice(b,b+1),8===b&&(g=d),isNaN(d)){for(c=0;c'); - } + } } }, styleURL: function() { @@ -19109,7 +19109,7 @@ return Popper; offsetAmt = (parseInt(offsetAmt)+parseInt(this.settings.spacing)) + this.$ele.outerHeight(); this.reposition(offsetAmt); } - + if ($.isFunction(self.settings.onShow)) { self.settings.onShow.call(this.$ele); } @@ -19133,7 +19133,7 @@ return Popper; bind: function() { var self = this; - this.$ele.find('[data-notify="dismiss"]').on('click', function() { + this.$ele.find('[data-notify="dismiss"]').on('click', function() { self.close(); }) @@ -19167,8 +19167,8 @@ return Popper; hasAnimation = false; this.$ele.data('closing', 'true').addClass(this.settings.animate.exit); - self.reposition(posX); - + self.reposition(posX); + if ($.isFunction(self.settings.onClose)) { self.settings.onClose.call(this.$ele); } @@ -21148,7 +21148,7 @@ S2.define('select2/selection/allowClear',[ return; } - var removeAll = this.options.get('translations').get('removeAllItems'); + var removeAll = this.options.get('translations').get('removeAllItems'); var $remove = $( '' + @@ -29428,7 +29428,7 @@ S2.define('jquery.select2',[ '' + '', contTemplate: '', - footTemplate: '' + + footTemplate: '' + '' + '' + '' @@ -29898,13 +29898,35 @@ function customConfirm(opts){ return $.confirm($.extend({}, defaultOpts, opts)) } -function show_success_flash(message) { +function customLoading(opts) { + var loading; + var defaultOpts = { + content: opts.ajax, + contentLoaded: function(){ + setTimeout(function(){ + loading.close() + }, 200); + } + } + loading = $.confirm($.extend({}, defaultOpts, opts)); + return loading; +} + +function show_success_flash(message){ $.notify({ message: message || '操作成功' },{ type: 'success' }); } + +function showErrorNotify(message){ + $.notify({ + message: message || '操作失败' + },{ + type: 'danger' + }); +} ; (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : @@ -38504,7 +38526,7 @@ ZImage.prototype = { // Draw rect text if (style.text != null) { // Only restore transform when needs draw text. - this.restoreTransform(ctx); + this.restoreTransform(ctx); this.drawRectText(ctx, this.getBoundingRect()); } }, @@ -44048,7 +44070,7 @@ Path.prototype = { // Draw rect text if (style.text != null) { // Only restore transform when needs draw text. - this.restoreTransform(ctx); + this.restoreTransform(ctx); this.drawRectText(ctx, this.getBoundingRect()); } }, @@ -75940,7 +75962,7 @@ SeriesModel.extend({ return tree.data; }, - + /** * Make the configuration 'orient' backward compatibly, with 'horizontal = LR', 'vertical = TB'. * @returns {string} orient @@ -76805,7 +76827,7 @@ function commonLayout(seriesModel, api) { var width = 0; var height = 0; var separation$$1 = null; - + if (layout === 'radial') { width = 2 * Math.PI; height = Math.min(layoutInfo.height, layoutInfo.width) / 2; @@ -76862,7 +76884,7 @@ function commonLayout(seriesModel, api) { }); } else { - var orient = seriesModel.getOrient(); + var orient = seriesModel.getOrient(); if (orient === 'RL' || orient === 'LR') { ky = height / (right.getLayout().x + delta + tx); kx = width / ((bottom.depth - 1) || 1); @@ -76886,7 +76908,7 @@ function commonLayout(seriesModel, api) { }); } } - } + } } /* @@ -87518,7 +87540,7 @@ extendChartView({ var width = layoutInfo.width; // view height var height = layoutInfo.height; - + var nodeData = seriesModel.getData(); var edgeData = seriesModel.getData('edge'); @@ -87643,12 +87665,12 @@ extendChartView({ localY: this.shape.y / height }); }; - + el.draggable = true; el.cursor = 'move'; }); } - + if (!this._data && seriesModel.get('animation')) { group.setClipPath(createGridClipShape$2(group.getBoundingRect(), seriesModel, function () { group.removeClipPath(); @@ -87932,7 +87954,7 @@ function computeNodeValues(nodes) { /** * Compute the x-position for each node. - * + * * Here we use Kahn algorithm to detect cycle when we traverse * the node to computer the initial x position. * @@ -87962,7 +87984,7 @@ function computeNodeBreadths(nodes, edges, nodeWidth, width) { zeroIndegrees.push(nodes[i]); } } - + while (zeroIndegrees.length) { each$1(zeroIndegrees, function (node) { node.setLayout({x: x}, true); @@ -87977,18 +87999,18 @@ function computeNodeBreadths(nodes, edges, nodeWidth, width) { } }); }); - + ++x; zeroIndegrees = nextNode; nextNode = []; } - + for (var i = 0; i < remainEdges.length; i++) { if (__DEV__) { if (remainEdges[i] === 1) { throw new Error('Sankey is a DAG, the original data has cycle!'); } - } + } } moveSinksRight(nodes, x); @@ -88296,7 +88318,7 @@ var sankeyVisual = function (ecModel, payload) { maxValue = nodeValue; } }); - + each$1(nodes, function (node) { var mapping = new VisualMapping({ type: 'color', @@ -88304,7 +88326,7 @@ var sankeyVisual = function (ecModel, payload) { dataExtent: [minValue, maxValue], visual: seriesModel.get('color') }); - + var mapValueToColor = mapping.mapValueToVisual(node.getLayout().value); node.setVisual('color', mapValueToColor); // If set itemStyle.normal.color @@ -97332,10 +97354,10 @@ var sunburstLayout = function (seriesType, ecModel, api, payload) { ? unitRadian : (value * unitRadian); if (angle < minAngle) { angle = minAngle; - + } else { - + } endAngle = startAngle + dir * angle; @@ -130129,8 +130151,8 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); /* * Editor.md * - * @file editormd.js - * @version v1.5.0 + * @file editormd.js + * @version v1.5.0 * @description Open source online markdown editor. * @license MIT License * @author Pandao @@ -130141,10 +130163,10 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); ;(function(factory) { "use strict"; - + // CommonJS/Node.js if (typeof require === "function" && typeof exports === "object" && typeof module === "object") - { + { module.exports = factory; } else if (typeof define === "function") // AMD/CMD/Sea.js @@ -130152,60 +130174,60 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); if (define.amd) // for Require.js { /* Require.js define replace */ - } - else + } + else { define(["jquery"], factory); // for Sea.js } - } + } else - { + { window.editormd = factory(); } - -}(function() { + +}(function() { /* Require.js assignment replace */ - + "use strict"; - + var $ = (typeof (jQuery) !== "undefined") ? jQuery : Zepto; if (typeof ($) === "undefined") { return ; } - + /** * editormd - * + * * @param {String} id 编辑器的ID * @param {Object} options 配置选项 Key/Value * @returns {Object} editormd 返回editormd对象 */ - + var editormd = function (id, options) { return new editormd.fn.init(id, options); }; - + editormd.title = editormd.$name = "Editor.md"; editormd.version = "1.5.0"; editormd.homePage = "https://pandao.github.io/editor.md/"; editormd.classPrefix = "editormd-"; - + editormd.toolbarModes = { full : [ - "undo", "redo", "|", - "bold", "del", "italic", "quote", "ucwords", "uppercase", "lowercase", "|", - "h1", "h2", "h3", "h4", "h5", "h6", "|", + "undo", "redo", "|", + "bold", "del", "italic", "quote", "ucwords", "uppercase", "lowercase", "|", + "h1", "h2", "h3", "h4", "h5", "h6", "|", "list-ul", "list-ol", "hr", "|", "link", "reference-link", "image", "code", "preformatted-text", "code-block", "table", "datetime", "emoji", "html-entities", "pagebreak", "|", "goto-line", "watch", "preview", "fullscreen", "clear", "search", "|", "help", "info" ], simple : [ - "undo", "redo", "|", - "bold", "del", "italic", "quote", "uppercase", "lowercase", "|", - "h1", "h2", "h3", "h4", "h5", "h6", "|", + "undo", "redo", "|", + "bold", "del", "italic", "quote", "uppercase", "lowercase", "|", + "h1", "h2", "h3", "h4", "h5", "h6", "|", "list-ul", "list-ol", "hr", "|", "watch", "preview", "fullscreen", "|", "help", "info" @@ -130216,7 +130238,7 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); "help", "info" ] }; - + editormd.defaults = { mode : "gfm", //gfm or markdown name : "", // Form element name @@ -130261,7 +130283,7 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); fontSize : "13px", saveHTMLToTextarea : false, disabledKeyMaps : [], - + onload : function() {}, onresize : function() {}, onchange : function() {}, @@ -130273,20 +130295,20 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); onfullscreenExit : function() {}, onscroll : function() {}, onpreviewscroll : function() {}, - + imageUpload : false, imageFormats : ["jpg", "jpeg", "gif", "png", "bmp", "webp"], imageUploadURL : "", crossDomainUpload : false, uploadCallbackURL : "", - + toc : true, // Table of contents tocm : false, // Using [TOCM], auto create ToC dropdown menu tocTitle : "", // for ToC dropdown menu btn tocDropdown : false, tocContainer : "", tocStartLevel : 1, // Said from H1 to create ToC - htmlDecode : false, // Open the HTML tag identification + htmlDecode : false, // Open the HTML tag identification pageBreak : true, // Enable parse page break [========] atLink : true, // for @link emailLink : true, // for email address auto link @@ -130298,7 +130320,7 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); flowChart : false, // flowChart.js only support IE9+ sequenceDiagram : false, // sequenceDiagram.js only support IE9+ previewCodeHighlight : true, - + toolbar : true, // show/hide toolbar toolbarAutoFixed : true, // on window scroll auto fixed position toolbarIcons : "full", @@ -130314,7 +130336,7 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); toolbarCustomIcons : { // using html tag create toolbar icon, unused default tag. lowercase : "a", "ucwords" : "Aa" - }, + }, toolbarIconsClass : { undo : "fa-undo", redo : "fa-repeat", @@ -130352,9 +130374,9 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); clear : "fa-eraser", help : "fa-question-circle", info : "fa-info-circle" - }, + }, toolbarIconTexts : {}, - + lang : { name : "zh-cn", description : "开源在线Markdown编辑器
    Open source online Markdown editor.", @@ -130432,11 +130454,11 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); formatNotAllowed : "错误:只允许上传图片文件,允许上传的图片文件格式有:" }, preformattedText : { - title : "添加预格式文本或代码块", + title : "添加预格式文本或代码块", emptyAlert : "错误:请填写预格式文本或代码的内容。" }, codeBlock : { - title : "添加代码块", + title : "添加代码块", selectLabel : "代码语言:", selectDefaultText : "请选择代码语言", otherLanguage : "其他语言", @@ -130452,18 +130474,18 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); } } }; - + editormd.classNames = { tex : editormd.classPrefix + "tex" }; editormd.dialogZindex = 99999; - + editormd.$katex = null; editormd.$marked = null; editormd.$CodeMirror = null; editormd.$prettyPrint = null; - + var timer, flowchartTimer; editormd.prototype = editormd.fn = { @@ -130473,76 +130495,76 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); preview : false, fullscreen : false }, - + /** * 构造函数/实例初始化 * Constructor / instance initialization - * + * * @param {String} id 编辑器的ID * @param {Object} [options={}] 配置选项 Key/Value * @returns {editormd} 返回editormd的实例对象 */ - + init : function (id, options) { - + options = options || {}; - + if (typeof id === "object") { options = id; } - + var _this = this; - var classPrefix = this.classPrefix = editormd.classPrefix; + var classPrefix = this.classPrefix = editormd.classPrefix; var settings = this.settings = $.extend(true, editormd.defaults, options); - + id = (typeof id === "object") ? settings.id : id; - + var editor = this.editor = $("#" + id); - + this.id = id; this.lang = settings.lang; - + var classNames = this.classNames = { textarea : { html : classPrefix + "html-textarea", markdown : classPrefix + "markdown-textarea" } }; - - settings.pluginPath = (settings.pluginPath === "") ? settings.path + "../plugins/" : settings.pluginPath; - + + settings.pluginPath = (settings.pluginPath === "") ? settings.path + "../plugins/" : settings.pluginPath; + this.state.watching = (settings.watch) ? true : false; - + if ( !editor.hasClass("editormd") ) { editor.addClass("editormd"); } - + editor.css({ width : (typeof settings.width === "number") ? settings.width + "px" : settings.width, height : (typeof settings.height === "number") ? settings.height + "px" : settings.height }); - + if (settings.autoHeight) { editor.css("height", "auto"); } - + var markdownTextarea = this.markdownTextarea = editor.children("textarea"); - + if (markdownTextarea.length < 1) { editor.append(""); markdownTextarea = this.markdownTextarea = editor.children("textarea"); } - + markdownTextarea.addClass(classNames.textarea.markdown).attr("placeholder", settings.placeholder); - + if (typeof markdownTextarea.attr("name") === "undefined" || markdownTextarea.attr("name") === "") { markdownTextarea.attr("name", (settings.name !== "") ? settings.name : id + "-markdown-doc"); } - + var appendElements = [ (!settings.readOnly) ? "" : "", ( (settings.saveHTMLToTextarea) ? "" : "" ), @@ -130550,114 +130572,114 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); "
    ", "
    " ].join("\n"); - + editor.append(appendElements).addClass(classPrefix + "vertical"); - - if (settings.theme !== "") + + if (settings.theme !== "") { editor.addClass(classPrefix + "theme-" + settings.theme); } - - this.mask = editor.children("." + classPrefix + "mask"); + + this.mask = editor.children("." + classPrefix + "mask"); this.containerMask = editor.children("." + classPrefix + "container-mask"); - + if (settings.markdown !== "") { markdownTextarea.val(settings.markdown); } - + if (settings.appendMarkdown !== "") { markdownTextarea.val(markdownTextarea.val() + settings.appendMarkdown); } - - this.htmlTextarea = editor.children("." + classNames.textarea.html); + + this.htmlTextarea = editor.children("." + classNames.textarea.html); this.preview = editor.children("." + classPrefix + "preview"); this.previewContainer = this.preview.children("." + classPrefix + "preview-container"); - - if (settings.previewTheme !== "") + + if (settings.previewTheme !== "") { this.preview.addClass(classPrefix + "preview-theme-" + settings.previewTheme); } - + if (typeof define === "function" && define.amd) { - if (typeof katex !== "undefined") + if (typeof katex !== "undefined") { editormd.$katex = katex; } - - if (settings.searchReplace && !settings.readOnly) + + if (settings.searchReplace && !settings.readOnly) { editormd.loadCSS(settings.path + "codemirror/addon/dialog/dialog"); editormd.loadCSS(settings.path + "codemirror/addon/search/matchesonscrollbar"); } } - + if ((typeof define === "function" && define.amd) || !settings.autoLoadModules) { if (typeof CodeMirror !== "undefined") { editormd.$CodeMirror = CodeMirror; } - + if (typeof marked !== "undefined") { editormd.$marked = marked; } - + this.setCodeMirror().setToolbar().loadedDisplay(); - } - else + } + else { this.loadQueues(); } return this; }, - + /** * 所需组件加载队列 * Required components loading queue - * + * * @returns {editormd} 返回editormd的实例对象 */ - + loadQueues : function() { var _this = this; var settings = this.settings; var loadPath = settings.path; - + var loadFlowChartOrSequenceDiagram = function() { - - if (editormd.isIE8) + + if (editormd.isIE8) { _this.loadedDisplay(); - + return ; } - if (settings.flowChart || settings.sequenceDiagram) + if (settings.flowChart || settings.sequenceDiagram) { editormd.loadScript(loadPath + "raphael.min", function() { - editormd.loadScript(loadPath + "underscore.min", function() { + editormd.loadScript(loadPath + "underscore.min", function() { - if (!settings.flowChart && settings.sequenceDiagram) + if (!settings.flowChart && settings.sequenceDiagram) { editormd.loadScript(loadPath + "sequence-diagram.min", function() { _this.loadedDisplay(); }); } - else if (settings.flowChart && !settings.sequenceDiagram) - { - editormd.loadScript(loadPath + "flowchart.min", function() { + else if (settings.flowChart && !settings.sequenceDiagram) + { + editormd.loadScript(loadPath + "flowchart.min", function() { editormd.loadScript(loadPath + "jquery.flowchart.min", function() { _this.loadedDisplay(); }); }); } - else if (settings.flowChart && settings.sequenceDiagram) - { - editormd.loadScript(loadPath + "flowchart.min", function() { + else if (settings.flowChart && settings.sequenceDiagram) + { + editormd.loadScript(loadPath + "flowchart.min", function() { editormd.loadScript(loadPath + "jquery.flowchart.min", function() { editormd.loadScript(loadPath + "sequence-diagram.min", function() { _this.loadedDisplay(); @@ -130668,157 +130690,157 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); }); }); - } + } else { _this.loadedDisplay(); } - }; + }; editormd.loadCSS(loadPath + "codemirror/codemirror.min"); - + if (settings.searchReplace && !settings.readOnly) { editormd.loadCSS(loadPath + "codemirror/addon/dialog/dialog"); editormd.loadCSS(loadPath + "codemirror/addon/search/matchesonscrollbar"); } - + if (settings.codeFold) { - editormd.loadCSS(loadPath + "codemirror/addon/fold/foldgutter"); + editormd.loadCSS(loadPath + "codemirror/addon/fold/foldgutter"); } - + editormd.loadScript(loadPath + "codemirror/codemirror.min", function() { editormd.$CodeMirror = CodeMirror; - + editormd.loadScript(loadPath + "codemirror/modes.min", function() { - + editormd.loadScript(loadPath + "codemirror/addons.min", function() { - + _this.setCodeMirror(); - - if (settings.mode !== "gfm" && settings.mode !== "markdown") + + if (settings.mode !== "gfm" && settings.mode !== "markdown") { _this.loadedDisplay(); - + return false; } - + _this.setToolbar(); editormd.loadScript(loadPath + "marked.min", function() { editormd.$marked = marked; - - if (settings.previewCodeHighlight) + + if (settings.previewCodeHighlight) { editormd.loadScript(loadPath + "prettify.min", function() { loadFlowChartOrSequenceDiagram(); }); - } + } else - { + { loadFlowChartOrSequenceDiagram(); } }); - + }); - + }); - + }); return this; }, - + /** * 设置 Editor.md 的整体主题,主要是工具栏 * Setting Editor.md theme - * + * * @returns {editormd} 返回editormd的实例对象 */ - + setTheme : function(theme) { var editor = this.editor; var oldTheme = this.settings.theme; var themePrefix = this.classPrefix + "theme-"; - + editor.removeClass(themePrefix + oldTheme).addClass(themePrefix + theme); - + this.settings.theme = theme; - + return this; }, - + /** * 设置 CodeMirror(编辑区)的主题 * Setting CodeMirror (Editor area) theme - * + * * @returns {editormd} 返回editormd的实例对象 */ - - setEditorTheme : function(theme) { - var settings = this.settings; - settings.editorTheme = theme; - + + setEditorTheme : function(theme) { + var settings = this.settings; + settings.editorTheme = theme; + if (theme !== "default") { editormd.loadCSS(settings.path + "codemirror/theme/" + settings.editorTheme); } - + this.cm.setOption("theme", theme); - + return this; }, - + /** * setEditorTheme() 的别名 * setEditorTheme() alias - * + * * @returns {editormd} 返回editormd的实例对象 */ - - setCodeMirrorTheme : function (theme) { + + setCodeMirrorTheme : function (theme) { this.setEditorTheme(theme); - + return this; }, - + /** * 设置 Editor.md 的主题 * Setting Editor.md theme - * + * * @returns {editormd} 返回editormd的实例对象 */ - - setPreviewTheme : function(theme) { + + setPreviewTheme : function(theme) { var preview = this.preview; var oldTheme = this.settings.previewTheme; var themePrefix = this.classPrefix + "preview-theme-"; - + preview.removeClass(themePrefix + oldTheme).addClass(themePrefix + theme); - + this.settings.previewTheme = theme; - + return this; }, - + /** * 配置和初始化CodeMirror组件 * CodeMirror initialization - * + * * @returns {editormd} 返回editormd的实例对象 */ - - setCodeMirror : function() { + + setCodeMirror : function() { var settings = this.settings; var editor = this.editor; - + if (settings.editorTheme !== "default") { editormd.loadCSS(settings.path + "codemirror/theme/" + settings.editorTheme); } - + var codeMirrorConfig = { mode : settings.mode, theme : settings.editorTheme, @@ -130831,8 +130853,8 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); lineNumbers : settings.lineNumbers, lineWrapping : settings.lineWrapping, extraKeys : { - "Ctrl-Q": function(cm) { - cm.foldCode(cm.getCursor()); + "Ctrl-Q": function(cm) { + cm.foldCode(cm.getCursor()); } }, foldGutter : settings.codeFold, @@ -130845,10 +130867,10 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); showTrailingSpace : settings.showTrailingSpace, highlightSelectionMatches : ( (!settings.matchWordHighlight) ? false : { showToken: (settings.matchWordHighlight === "onselected") ? false : /\w/ } ) }; - + this.codeEditor = this.cm = editormd.$CodeMirror.fromTextArea(this.markdownTextarea[0], codeMirrorConfig); this.codeMirror = this.cmElement = editor.children(".CodeMirror"); - + if (settings.value !== "") { this.cm.setValue(settings.value); @@ -130858,13 +130880,13 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); fontSize : settings.fontSize, width : (!settings.watch) ? "100%" : "50%" }); - + if (settings.autoHeight) { this.codeMirror.css("height", "auto"); this.cm.setOption("viewportMargin", Infinity); } - + if (!settings.lineNumbers) { this.codeMirror.find(".CodeMirror-gutters").css("border-right", "none"); @@ -130872,149 +130894,149 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); return this; }, - + /** * 获取CodeMirror的配置选项 * Get CodeMirror setting options - * + * * @returns {Mixed} return CodeMirror setting option value */ - - getCodeMirrorOption : function(key) { + + getCodeMirrorOption : function(key) { return this.cm.getOption(key); }, - + /** * 配置和重配置CodeMirror的选项 * CodeMirror setting options / resettings - * + * * @returns {editormd} 返回editormd的实例对象 */ - + setCodeMirrorOption : function(key, value) { - + this.cm.setOption(key, value); - + return this; }, - + /** * 添加 CodeMirror 键盘快捷键 * Add CodeMirror keyboard shortcuts key map - * + * * @returns {editormd} 返回editormd的实例对象 */ - + addKeyMap : function(map, bottom) { this.cm.addKeyMap(map, bottom); - + return this; }, - + /** * 移除 CodeMirror 键盘快捷键 * Remove CodeMirror keyboard shortcuts key map - * + * * @returns {editormd} 返回editormd的实例对象 */ - + removeKeyMap : function(map) { this.cm.removeKeyMap(map); - + return this; }, - + /** * 跳转到指定的行 * Goto CodeMirror line - * + * * @param {String|Intiger} line line number or "first"|"last" * @returns {editormd} 返回editormd的实例对象 */ - + gotoLine : function (line) { - + var settings = this.settings; - + if (!settings.gotoLine) { return this; } - + var cm = this.cm; var editor = this.editor; var count = cm.lineCount(); var preview = this.preview; - + if (typeof line === "string") { if(line === "last") { line = count; } - + if (line === "first") { line = 1; } } - - if (typeof line !== "number") - { + + if (typeof line !== "number") + { alert("Error: The line number must be an integer."); return this; } - + line = parseInt(line) - 1; - + if (line > count) { alert("Error: The line number range 1-" + count); - + return this; } - + cm.setCursor( {line : line, ch : 0} ); - + var scrollInfo = cm.getScrollInfo(); - var clientHeight = scrollInfo.clientHeight; + var clientHeight = scrollInfo.clientHeight; var coords = cm.charCoords({line : line, ch : 0}, "local"); - + cm.scrollTo(null, (coords.top + coords.bottom - clientHeight) / 2); - + if (settings.watch) - { + { var cmScroll = this.codeMirror.find(".CodeMirror-scroll")[0]; - var height = $(cmScroll).height(); - var scrollTop = cmScroll.scrollTop; + var height = $(cmScroll).height(); + var scrollTop = cmScroll.scrollTop; var percent = (scrollTop / cmScroll.scrollHeight); if (scrollTop === 0) { preview.scrollTop(0); - } + } else if (scrollTop + height >= cmScroll.scrollHeight - 16) - { - preview.scrollTop(preview[0].scrollHeight); - } + { + preview.scrollTop(preview[0].scrollHeight); + } else - { + { preview.scrollTop(preview[0].scrollHeight * percent); } } cm.focus(); - + return this; }, - + /** * 扩展当前实例对象,可同时设置多个或者只设置一个 * Extend editormd instance object, can mutil setting. - * + * * @returns {editormd} this(editormd instance object.) */ - + extend : function() { if (typeof arguments[1] !== "undefined") { @@ -131025,7 +131047,7 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); this[arguments[0]] = arguments[1]; } - + if (typeof arguments[0] === "object" && typeof arguments[0].length === "undefined") { $.extend(true, this, arguments[0]); @@ -131033,168 +131055,168 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); return this; }, - + /** * 设置或扩展当前实例对象,单个设置 * Extend editormd instance object, one by one - * + * * @param {String|Object} key option key * @param {String|Object} value option value * @returns {editormd} this(editormd instance object.) */ - + set : function (key, value) { - + if (typeof value !== "undefined" && typeof value === "function") { value = $.proxy(value, this); } - + this[key] = value; return this; }, - + /** * 重新配置 * Resetting editor options - * + * * @param {String|Object} key option key * @param {String|Object} value option value * @returns {editormd} this(editormd instance object.) */ - + config : function(key, value) { var settings = this.settings; - + if (typeof key === "object") { settings = $.extend(true, settings, key); } - + if (typeof key === "string") { settings[key] = value; } - + this.settings = settings; this.recreate(); - + return this; }, - + /** * 注册事件处理方法 * Bind editor event handle - * + * * @param {String} eventType event type * @param {Function} callback 回调函数 * @returns {editormd} this(editormd instance object.) */ - + on : function(eventType, callback) { var settings = this.settings; - - if (typeof settings["on" + eventType] !== "undefined") - { - settings["on" + eventType] = $.proxy(callback, this); + + if (typeof settings["on" + eventType] !== "undefined") + { + settings["on" + eventType] = $.proxy(callback, this); } return this; }, - + /** * 解除事件处理方法 * Unbind editor event handle - * + * * @param {String} eventType event type * @returns {editormd} this(editormd instance object.) */ - + off : function(eventType) { var settings = this.settings; - - if (typeof settings["on" + eventType] !== "undefined") + + if (typeof settings["on" + eventType] !== "undefined") { settings["on" + eventType] = function(){}; } - + return this; }, - + /** * 显示工具栏 * Display toolbar - * + * * @param {Function} [callback=function(){}] 回调函数 * @returns {editormd} 返回editormd的实例对象 */ - + showToolbar : function(callback) { var settings = this.settings; - + if(settings.readOnly) { return this; } - + if (settings.toolbar && (this.toolbar.length < 1 || this.toolbar.find("." + this.classPrefix + "menu").html() === "") ) { this.setToolbar(); } - - settings.toolbar = true; - + + settings.toolbar = true; + this.toolbar.show(); this.resize(); - + $.proxy(callback || function(){}, this)(); return this; }, - + /** * 隐藏工具栏 * Hide toolbar - * + * * @param {Function} [callback=function(){}] 回调函数 * @returns {editormd} this(editormd instance object.) */ - - hideToolbar : function(callback) { + + hideToolbar : function(callback) { var settings = this.settings; - - settings.toolbar = false; + + settings.toolbar = false; this.toolbar.hide(); this.resize(); - + $.proxy(callback || function(){}, this)(); return this; }, - + /** * 页面滚动时工具栏的固定定位 * Set toolbar in window scroll auto fixed position - * + * * @returns {editormd} 返回editormd的实例对象 */ - + setToolbarAutoFixed : function(fixed) { - + var state = this.state; var editor = this.editor; var toolbar = this.toolbar; var settings = this.settings; - + if (typeof fixed !== "undefined") { settings.toolbarAutoFixed = fixed; } - + var autoFixedHandle = function(){ var $window = $(window); var top = $window.scrollTop(); - + if (!settings.toolbarAutoFixed) { return false; @@ -131217,7 +131239,7 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); }); } }; - + if (!state.fullscreen && !state.preview && settings.toolbar && settings.toolbarAutoFixed) { $(window).bind("scroll", autoFixedHandle); @@ -131225,58 +131247,58 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); return this; }, - + /** * 配置和初始化工具栏 * Set toolbar and Initialization - * + * * @returns {editormd} 返回editormd的实例对象 */ - + setToolbar : function() { - var settings = this.settings; - + var settings = this.settings; + if(settings.readOnly) { return this; } - + var editor = this.editor; var preview = this.preview; var classPrefix = this.classPrefix; - + var toolbar = this.toolbar = editor.children("." + classPrefix + "toolbar"); - + if (settings.toolbar && toolbar.length < 1) - { + { var toolbarHTML = "
      "; - + editor.append(toolbarHTML); toolbar = this.toolbar = editor.children("." + classPrefix + "toolbar"); } - - if (!settings.toolbar) + + if (!settings.toolbar) { toolbar.hide(); - + return this; } - + toolbar.show(); - - var icons = (typeof settings.toolbarIcons === "function") ? settings.toolbarIcons() + + var icons = (typeof settings.toolbarIcons === "function") ? settings.toolbarIcons() : ((typeof settings.toolbarIcons === "string") ? editormd.toolbarModes[settings.toolbarIcons] : settings.toolbarIcons); - + var toolbarMenu = toolbar.find("." + this.classPrefix + "menu"), menu = ""; var pullRight = false; - + for (var i = 0, len = icons.length; i < len; i++) { var name = icons[i]; - if (name === "||") - { + if (name === "||") + { pullRight = true; - } + } else if (name === "|") { menu += "
    • |
    • "; @@ -131285,26 +131307,26 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); { var isHeader = (/h(\d)/.test(name)); var index = name; - + if (name === "watch" && !settings.watch) { index = "unwatch"; } - + var title = settings.lang.toolbar[index]; var iconTexts = settings.toolbarIconTexts[index]; var iconClass = settings.toolbarIconsClass[index]; - + title = (typeof title === "undefined") ? "" : title; iconTexts = (typeof iconTexts === "undefined") ? "" : iconTexts; iconClass = (typeof iconClass === "undefined") ? "" : iconClass; var menuItem = pullRight ? "
    • " : "
    • "; - + if (typeof settings.toolbarCustomIcons[name] !== "undefined" && typeof settings.toolbarCustomIcons[name] !== "function") { menuItem += settings.toolbarCustomIcons[name]; } - else + else { menuItem += ""; menuItem += ""+((isHeader) ? name.toUpperCase() : ( (iconClass === "") ? iconTexts : "") ) + ""; @@ -131318,64 +131340,64 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); } toolbarMenu.html(menu); - + toolbarMenu.find("[title=\"Lowercase\"]").attr("title", settings.lang.toolbar.lowercase); toolbarMenu.find("[title=\"ucwords\"]").attr("title", settings.lang.toolbar.ucwords); - + this.setToolbarHandler(); this.setToolbarAutoFixed(); return this; }, - + /** * 工具栏图标事件处理对象序列 * Get toolbar icons event handlers - * + * * @param {Object} cm CodeMirror的实例对象 * @param {String} name 要获取的事件处理器名称 * @returns {Object} 返回处理对象序列 */ - + dialogLockScreen : function() { $.proxy(editormd.dialogLockScreen, this)(); - + return this; }, dialogShowMask : function(dialog) { $.proxy(editormd.dialogShowMask, this)(dialog); - + return this; }, - - getToolbarHandles : function(name) { + + getToolbarHandles : function(name) { var toolbarHandlers = this.toolbarHandlers = editormd.toolbarHandlers; - + return (name && typeof toolbarIconHandlers[name] !== "undefined") ? toolbarHandlers[name] : toolbarHandlers; }, - + /** * 工具栏图标事件处理器 * Bind toolbar icons event handle - * + * * @returns {editormd} 返回editormd的实例对象 */ - + setToolbarHandler : function() { var _this = this; var settings = this.settings; - + if (!settings.toolbar || settings.readOnly) { return this; } - + var toolbar = this.toolbar; var cm = this.cm; - var classPrefix = this.classPrefix; - var toolbarIcons = this.toolbarIcons = toolbar.find("." + classPrefix + "menu > li > a"); - var toolbarIconHandlers = this.getToolbarHandles(); - + var classPrefix = this.classPrefix; + var toolbarIcons = this.toolbarIcons = toolbar.find("." + classPrefix + "menu > li > a"); + var toolbarIconHandlers = this.getToolbarHandles(); + toolbarIcons.bind(editormd.mouseOrTouch("click", "touchend"), function(event) { var icon = $(this).children(".fa"); @@ -131386,23 +131408,23 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); if (name === "") { return ; } - + _this.activeIcon = icon; - if (typeof toolbarIconHandlers[name] !== "undefined") + if (typeof toolbarIconHandlers[name] !== "undefined") { $.proxy(toolbarIconHandlers[name], _this)(cm); } - else + else { - if (typeof settings.toolbarHandlers[name] !== "undefined") + if (typeof settings.toolbarHandlers[name] !== "undefined") { $.proxy(settings.toolbarHandlers[name], _this)(cm, icon, cursor, selection); } } - - if (name !== "link" && name !== "reference-link" && name !== "image" && name !== "code-block" && - name !== "preformatted-text" && name !== "watch" && name !== "preview" && name !== "search" && name !== "fullscreen" && name !== "info") + + if (name !== "link" && name !== "reference-link" && name !== "image" && name !== "code-block" && + name !== "preformatted-text" && name !== "watch" && name !== "preview" && name !== "search" && name !== "fullscreen" && name !== "info") { cm.focus(); } @@ -131413,31 +131435,31 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); return this; }, - + /** * 动态创建对话框 * Creating custom dialogs - * + * * @param {Object} options 配置项键值对 Key/Value * @returns {dialog} 返回创建的dialog的jQuery实例对象 */ - - createDialog : function(options) { + + createDialog : function(options) { return $.proxy(editormd.createDialog, this)(options); }, - + /** * 创建关于Editor.md的对话框 * Create about Editor.md dialog - * + * * @returns {editormd} 返回editormd的实例对象 */ - + createInfoDialog : function() { var _this = this; var editor = this.editor; - var classPrefix = this.classPrefix; - + var classPrefix = this.classPrefix; + var infoDialogHTML = [ "
      ", "
      ", @@ -131451,30 +131473,30 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); ].join("\n"); editor.append(infoDialogHTML); - + var infoDialog = this.infoDialog = editor.children("." + classPrefix + "dialog-info"); infoDialog.find("." + classPrefix + "dialog-close").bind(editormd.mouseOrTouch("click", "touchend"), function() { _this.hideInfoDialog(); }); - + infoDialog.css("border", (editormd.isIE8) ? "1px solid #ddd" : "").css("z-index", editormd.dialogZindex).show(); - + this.infoDialogPosition(); return this; }, - + /** * 关于Editor.md对话居中定位 * Editor.md dialog position handle - * + * * @returns {editormd} 返回editormd的实例对象 */ - + infoDialogPosition : function() { var infoDialog = this.infoDialog; - + var _infoDialogPosition = function() { infoDialog.css({ top : ($(window).height() - infoDialog.height()) / 2 + "px", @@ -131485,33 +131507,33 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); _infoDialogPosition(); $(window).resize(_infoDialogPosition); - + return this; }, - + /** * 显示关于Editor.md * Display about Editor.md dialog - * + * * @returns {editormd} 返回editormd的实例对象 */ - + showInfoDialog : function() { $("html,body").css("overflow-x", "hidden"); - + var _this = this; var editor = this.editor; - var settings = this.settings; + var settings = this.settings; var infoDialog = this.infoDialog = editor.children("." + this.classPrefix + "dialog-info"); - + if (infoDialog.length < 1) { this.createInfoDialog(); } - + this.lockScreen(true); - + this.mask.css({ opacity : settings.dialogMaskOpacity, backgroundColor : settings.dialogMaskBgColor @@ -131523,15 +131545,15 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); return this; }, - + /** * 隐藏关于Editor.md * Hide about Editor.md dialog - * + * * @returns {editormd} 返回editormd的实例对象 */ - - hideInfoDialog : function() { + + hideInfoDialog : function() { $("html,body").css("overflow-x", ""); this.infoDialog.hide(); this.mask.hide(); @@ -131539,116 +131561,116 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); return this; }, - + /** * 锁屏 * lock screen - * + * * @param {Boolean} lock Boolean 布尔值,是否锁屏 * @returns {editormd} 返回editormd的实例对象 */ - + lockScreen : function(lock) { editormd.lockScreen(lock); this.resize(); return this; }, - + /** * 编辑器界面重建,用于动态语言包或模块加载等 * Recreate editor - * + * * @returns {editormd} 返回editormd的实例对象 */ - + recreate : function() { var _this = this; var editor = this.editor; var settings = this.settings; - + this.codeMirror.remove(); - + this.setCodeMirror(); - if (!settings.readOnly) + if (!settings.readOnly) { if (editor.find(".editormd-dialog").length > 0) { editor.find(".editormd-dialog").remove(); } - - if (settings.toolbar) - { - this.getToolbarHandles(); + + if (settings.toolbar) + { + this.getToolbarHandles(); this.setToolbar(); } } - + this.loadedDisplay(true); return this; }, - + /** * 高亮预览HTML的pre代码部分 * highlight of preview codes - * + * * @returns {editormd} 返回editormd的实例对象 */ - - previewCodeHighlight : function() { + + previewCodeHighlight : function() { var settings = this.settings; var previewContainer = this.previewContainer; - - if (settings.previewCodeHighlight) + + if (settings.previewCodeHighlight) { previewContainer.find("pre").addClass("prettyprint linenums"); - + if (typeof prettyPrint !== "undefined") - { + { prettyPrint(); } } return this; }, - + /** * 解析TeX(KaTeX)科学公式 * TeX(KaTeX) Renderer - * + * * @returns {editormd} 返回editormd的实例对象 */ - + katexRender : function() { - + if (timer === null) { return this; } - + this.previewContainer.find("." + editormd.classNames.tex).each(function(){ var tex = $(this); editormd.$katex.render(tex.text(), tex[0]); - + tex.find(".katex").css("font-size", "1.6em"); - }); + }); return this; }, - + /** * 解析和渲染流程图及时序图 * FlowChart and SequenceDiagram Renderer - * + * * @returns {editormd} 返回editormd的实例对象 */ - + flowChartAndSequenceDiagramRender : function() { var $this = this; var settings = this.settings; var previewContainer = this.previewContainer; - + if (editormd.isIE8) { return this; } @@ -131657,20 +131679,20 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); if (flowchartTimer === null) { return this; } - - previewContainer.find(".flowchart").flowChart(); + + previewContainer.find(".flowchart").flowChart(); } if (settings.sequenceDiagram) { previewContainer.find(".sequence-diagram").sequenceDiagram({theme: "simple"}); } - + var preview = $this.preview; var codeMirror = $this.codeMirror; var codeView = codeMirror.find(".CodeMirror-scroll"); var height = codeView.height(); - var scrollTop = codeView.scrollTop(); + var scrollTop = codeView.scrollTop(); var percent = (scrollTop / codeView[0].scrollHeight); var tocHeight = 0; @@ -131678,43 +131700,43 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); tocHeight += $(this).height(); }); - var tocMenuHeight = preview.find(".editormd-toc-menu").height(); + var tocMenuHeight = preview.find(".editormd-toc-menu").height(); tocMenuHeight = (!tocMenuHeight) ? 0 : tocMenuHeight; - if (scrollTop === 0) + if (scrollTop === 0) { preview.scrollTop(0); - } + } else if (scrollTop + height >= codeView[0].scrollHeight - 16) - { - preview.scrollTop(preview[0].scrollHeight); - } + { + preview.scrollTop(preview[0].scrollHeight); + } else - { + { preview.scrollTop((preview[0].scrollHeight + tocHeight + tocMenuHeight) * percent); } return this; }, - + /** * 注册键盘快捷键处理 * Register CodeMirror keyMaps (keyboard shortcuts). - * + * * @param {Object} keyMap KeyMap key/value {"(Ctrl/Shift/Alt)-Key" : function(){}} * @returns {editormd} return this */ - + registerKeyMaps : function(keyMap) { - + var _this = this; var cm = this.cm; var settings = this.settings; var toolbarHandlers = editormd.toolbarHandlers; var disabledKeyMaps = settings.disabledKeyMaps; - + keyMap = keyMap || null; - + if (keyMap) { for (var i in keyMap) @@ -131734,7 +131756,7 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); { var _keyMap = editormd.keyMaps[k]; var handle = (typeof _keyMap === "string") ? $.proxy(toolbarHandlers[_keyMap], _this) : $.proxy(_keyMap, _this); - + if ($.inArray(k, ["F9", "F10", "F11"]) < 0 && $.inArray(k, disabledKeyMaps) < 0) { var _map = {}; @@ -131743,15 +131765,15 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); cm.addKeyMap(_map); } } - + $(window).keydown(function(event) { - + var keymaps = { "120" : "F9", "121" : "F10", "122" : "F11" }; - + if ( $.inArray(keymaps[event.keyCode], disabledKeyMaps) < 0 ) { switch (event.keyCode) @@ -131760,17 +131782,17 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); $.proxy(toolbarHandlers["watch"], _this)(); return false; break; - + case 121: $.proxy(toolbarHandlers["preview"], _this)(); return false; break; - + case 122: - $.proxy(toolbarHandlers["fullscreen"], _this)(); + $.proxy(toolbarHandlers["fullscreen"], _this)(); return false; break; - + default: break; } @@ -131780,53 +131802,53 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); return this; }, - + /** * 绑定同步滚动 - * + * * @returns {editormd} return this */ - + bindScrollEvent : function() { - + var _this = this; var preview = this.preview; var settings = this.settings; var codeMirror = this.codeMirror; var mouseOrTouch = editormd.mouseOrTouch; - + if (!settings.syncScrolling) { return this; } - - var cmBindScroll = function() { + + var cmBindScroll = function() { codeMirror.find(".CodeMirror-scroll").bind(mouseOrTouch("scroll", "touchmove"), function(event) { var height = $(this).height(); - var scrollTop = $(this).scrollTop(); + var scrollTop = $(this).scrollTop(); var percent = (scrollTop / $(this)[0].scrollHeight); - + var tocHeight = 0; - + preview.find(".markdown-toc-list").each(function(){ tocHeight += $(this).height(); }); - + var tocMenuHeight = preview.find(".editormd-toc-menu").height(); tocMenuHeight = (!tocMenuHeight) ? 0 : tocMenuHeight; - if (scrollTop === 0) + if (scrollTop === 0) { preview.scrollTop(0); - } + } else if (scrollTop + height >= $(this)[0].scrollHeight - 16) - { - preview.scrollTop(preview[0].scrollHeight); - } + { + preview.scrollTop(preview[0].scrollHeight); + } else { preview.scrollTop((preview[0].scrollHeight + tocHeight + tocMenuHeight) * percent); } - + $.proxy(settings.onscroll, _this)(event); }); }; @@ -131836,26 +131858,26 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); }; var previewBindScroll = function() { - + preview.bind(mouseOrTouch("scroll", "touchmove"), function(event) { var height = $(this).height(); - var scrollTop = $(this).scrollTop(); + var scrollTop = $(this).scrollTop(); var percent = (scrollTop / $(this)[0].scrollHeight); var codeView = codeMirror.find(".CodeMirror-scroll"); - if(scrollTop === 0) + if(scrollTop === 0) { codeView.scrollTop(0); } else if (scrollTop + height >= $(this)[0].scrollHeight) { - codeView.scrollTop(codeView[0].scrollHeight); + codeView.scrollTop(codeView[0].scrollHeight); } - else + else { codeView.scrollTop(codeView[0].scrollHeight * percent); } - + $.proxy(settings.onpreviewscroll, _this)(event); }); @@ -131863,7 +131885,7 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); var previewUnbindScroll = function() { preview.unbind(mouseOrTouch("scroll", "touchmove")); - }; + }; codeMirror.bind({ mouseover : cmBindScroll, @@ -131871,11 +131893,11 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); touchstart : cmBindScroll, touchend : cmUnbindScroll }); - + if (settings.syncScrolling === "single") { return this; } - + preview.bind({ mouseover : previewBindScroll, mouseout : previewUnbindScroll, @@ -131885,24 +131907,24 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); return this; }, - + bindChangeEvent : function() { - + var _this = this; var cm = this.cm; var settings = this.settings; - + if (!settings.syncScrolling) { return this; } - + cm.on("change", function(_cm, changeObj) { - + if (settings.watch) { _this.previewContainer.css("padding", settings.autoHeight ? "20px 20px 50px 40px" : "20px"); } - + timer = setTimeout(function() { clearTimeout(timer); _this.save(); @@ -131912,210 +131934,210 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); return this; }, - + /** * 加载队列完成之后的显示处理 * Display handle of the module queues loaded after. - * + * * @param {Boolean} recreate 是否为重建编辑器 * @returns {editormd} 返回editormd的实例对象 */ - + loadedDisplay : function(recreate) { - + recreate = recreate || false; - + var _this = this; var editor = this.editor; var preview = this.preview; var settings = this.settings; - + this.containerMask.hide(); - + this.save(); - + if (settings.watch) { preview.show(); } - + editor.data("oldWidth", editor.width()).data("oldHeight", editor.height()); // 为了兼容Zepto - + this.resize(); this.registerKeyMaps(); - + $(window).resize(function(){ _this.resize(); }); - + this.bindScrollEvent().bindChangeEvent(); - + if (!recreate) { $.proxy(settings.onload, this)(); } - + this.state.loaded = true; return this; }, - + /** * 设置编辑器的宽度 * Set editor width - * + * * @param {Number|String} width 编辑器宽度值 * @returns {editormd} 返回editormd的实例对象 */ - + width : function(width) { - - this.editor.css("width", (typeof width === "number") ? width + "px" : width); + + this.editor.css("width", (typeof width === "number") ? width + "px" : width); this.resize(); - + return this; }, - + /** * 设置编辑器的高度 * Set editor height - * + * * @param {Number|String} height 编辑器高度值 * @returns {editormd} 返回editormd的实例对象 */ - + height : function(height) { - - this.editor.css("height", (typeof height === "number") ? height + "px" : height); + + this.editor.css("height", (typeof height === "number") ? height + "px" : height); this.resize(); - + return this; }, - + /** * 调整编辑器的尺寸和布局 * Resize editor layout - * + * * @param {Number|String} [width=null] 编辑器宽度值 * @param {Number|String} [height=null] 编辑器高度值 * @returns {editormd} 返回editormd的实例对象 */ - + resize : function(width, height) { - + width = width || null; height = height || null; - + var state = this.state; var editor = this.editor; var preview = this.preview; var toolbar = this.toolbar; var settings = this.settings; var codeMirror = this.codeMirror; - + if (width) { editor.css("width", (typeof width === "number") ? width + "px" : width); } - + if (settings.autoHeight && !state.fullscreen && !state.preview) { editor.css("height", "auto"); codeMirror.css("height", "auto"); - } - else + } + else { - if (height) + if (height) { editor.css("height", (typeof height === "number") ? height + "px" : height); } - + if (state.fullscreen) { editor.height($(window).height()); } - if (settings.toolbar && !settings.readOnly) + if (settings.toolbar && !settings.readOnly) { codeMirror.css("margin-top", toolbar.height() + 1).height(editor.height() - toolbar.height()); - } + } else { codeMirror.css("margin-top", 0).height(editor.height()); } } - - if(settings.watch) + + if(settings.watch) { codeMirror.width(editor.width() / 2); preview.width((!state.preview) ? editor.width() / 2 : editor.width()); - + this.previewContainer.css("padding", settings.autoHeight ? "20px 20px 50px 40px" : "20px"); - - if (settings.toolbar && !settings.readOnly) + + if (settings.toolbar && !settings.readOnly) { preview.css("top", toolbar.height() + 1); - } - else + } + else { preview.css("top", 0); } - + if (settings.autoHeight && !state.fullscreen && !state.preview) { preview.height(""); } else - { + { var previewHeight = (settings.toolbar && !settings.readOnly) ? editor.height() - toolbar.height() : editor.height(); - + preview.height(previewHeight); } - } - else + } + else { codeMirror.width(editor.width()); preview.hide(); } - - if (state.loaded) + + if (state.loaded) { $.proxy(settings.onresize, this)(); } return this; }, - + /** * 解析和保存Markdown代码 * Parse & Saving Markdown source code - * + * * @returns {editormd} 返回editormd的实例对象 */ - + save : function() { - + if (timer === null) { return this; } - + var _this = this; var state = this.state; var settings = this.settings; - var cm = this.cm; + var cm = this.cm; var cmValue = cm.getValue(); var previewContainer = this.previewContainer; - if (settings.mode !== "gfm" && settings.mode !== "markdown") + if (settings.mode !== "gfm" && settings.mode !== "markdown") { this.markdownTextarea.val(cmValue); - + return this; } - + var marked = editormd.$marked; - var markdownToC = this.markdownToC = []; - var rendererOptions = this.markedRendererOptions = { + var markdownToC = this.markdownToC = []; + var rendererOptions = this.markedRendererOptions = { toc : settings.toc, tocm : settings.tocm, tocStartLevel : settings.tocStartLevel, @@ -132129,7 +132151,7 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); sequenceDiagram : settings.sequenceDiagram, previewCodeHighlight : settings.previewCodeHighlight, }; - + var markedOptions = this.markedOptions = { renderer : editormd.markedRenderer(markdownToC, rendererOptions), gfm : true, @@ -132140,74 +132162,74 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); smartLists : true, smartypants : true }; - + marked.setOptions(markedOptions); - + var newMarkdownDoc = editormd.$marked(cmValue, markedOptions); - + //console.info("cmValue", cmValue, newMarkdownDoc); - + newMarkdownDoc = editormd.filterHTMLTags(newMarkdownDoc, settings.htmlDecode); - + //console.error("cmValue", cmValue, newMarkdownDoc); - + this.markdownTextarea.text(cmValue); - + cm.save(); - - if (settings.saveHTMLToTextarea) + + if (settings.saveHTMLToTextarea) { this.htmlTextarea.text(newMarkdownDoc); } - + if(settings.watch || (!settings.watch && state.preview)) { previewContainer.html(newMarkdownDoc); this.previewCodeHighlight(); - - if (settings.toc) + + if (settings.toc) { var tocContainer = (settings.tocContainer === "") ? previewContainer : $(settings.tocContainer); var tocMenu = tocContainer.find("." + this.classPrefix + "toc-menu"); - + tocContainer.attr("previewContainer", (settings.tocContainer === "") ? "true" : "false"); - + if (settings.tocContainer !== "" && tocMenu.length > 0) { tocMenu.remove(); } - + editormd.markdownToCRenderer(markdownToC, tocContainer, settings.tocDropdown, settings.tocStartLevel); - + if (settings.tocDropdown || tocContainer.find("." + this.classPrefix + "toc-menu").length > 0) { editormd.tocDropdownMenu(tocContainer, (settings.tocTitle !== "") ? settings.tocTitle : this.lang.tocTitle); } - + if (settings.tocContainer !== "") { previewContainer.find(".markdown-toc").css("border", "none"); } } - + if (settings.tex) { - if (!editormd.kaTeXLoaded && settings.autoLoadModules) + if (!editormd.kaTeXLoaded && settings.autoLoadModules) { editormd.loadKaTeX(function() { editormd.$katex = katex; editormd.kaTeXLoaded = true; _this.katexRender(); }); - } - else + } + else { editormd.$katex = katex; this.katexRender(); } - } - + } + if (settings.flowChart || settings.sequenceDiagram) { flowchartTimer = setTimeout(function(){ @@ -132217,7 +132239,7 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); }, 10); } - if (state.loaded) + if (state.loaded) { $.proxy(settings.onchange, this)(); } @@ -132225,215 +132247,215 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); return this; }, - + /** * 聚焦光标位置 * Focusing the cursor position - * + * * @returns {editormd} 返回editormd的实例对象 */ - + focus : function() { this.cm.focus(); return this; }, - + /** * 设置光标的位置 * Set cursor position - * + * * @param {Object} cursor 要设置的光标位置键值对象,例:{line:1, ch:0} * @returns {editormd} 返回editormd的实例对象 */ - + setCursor : function(cursor) { this.cm.setCursor(cursor); return this; }, - + /** * 获取当前光标的位置 * Get the current position of the cursor - * + * * @returns {Cursor} 返回一个光标Cursor对象 */ - + getCursor : function() { return this.cm.getCursor(); }, - + /** * 设置光标选中的范围 * Set cursor selected ranges - * + * * @param {Object} from 开始位置的光标键值对象,例:{line:1, ch:0} * @param {Object} to 结束位置的光标键值对象,例:{line:1, ch:0} * @returns {editormd} 返回editormd的实例对象 */ - + setSelection : function(from, to) { - + this.cm.setSelection(from, to); - + return this; }, - + /** * 获取光标选中的文本 * Get the texts from cursor selected - * + * * @returns {String} 返回选中文本的字符串形式 */ - + getSelection : function() { return this.cm.getSelection(); }, - + /** * 设置光标选中的文本范围 * Set the cursor selection ranges - * + * * @param {Array} ranges cursor selection ranges array * @returns {Array} return this */ - + setSelections : function(ranges) { this.cm.setSelections(ranges); - + return this; }, - + /** * 获取光标选中的文本范围 * Get the cursor selection ranges - * + * * @returns {Array} return selection ranges array */ - + getSelections : function() { return this.cm.getSelections(); }, - + /** * 替换当前光标选中的文本或在当前光标处插入新字符 * Replace the text at the current cursor selected or insert a new character at the current cursor position - * + * * @param {String} value 要插入的字符值 * @returns {editormd} 返回editormd的实例对象 */ - + replaceSelection : function(value) { this.cm.replaceSelection(value); return this; }, - + /** * 在当前光标处插入新字符 * Insert a new character at the current cursor position * * 同replaceSelection()方法 * With the replaceSelection() method - * + * * @param {String} value 要插入的字符值 * @returns {editormd} 返回editormd的实例对象 */ - + insertValue : function(value) { this.replaceSelection(value); return this; }, - + /** * 追加markdown * append Markdown to editor - * + * * @param {String} md 要追加的markdown源文档 * @returns {editormd} 返回editormd的实例对象 */ - + appendMarkdown : function(md) { var settings = this.settings; var cm = this.cm; - + cm.setValue(cm.getValue() + md); - + return this; }, - + /** * 设置和传入编辑器的markdown源文档 * Set Markdown source document - * + * * @param {String} md 要传入的markdown源文档 * @returns {editormd} 返回editormd的实例对象 */ - + setMarkdown : function(md) { this.cm.setValue(md || this.settings.markdown); - + return this; }, - + /** * 获取编辑器的markdown源文档 * Set Editor.md markdown/CodeMirror value - * + * * @returns {editormd} 返回editormd的实例对象 */ - + getMarkdown : function() { return this.cm.getValue(); }, - + /** * 获取编辑器的源文档 * Get CodeMirror value - * + * * @returns {editormd} 返回editormd的实例对象 */ - + getValue : function() { return this.cm.getValue(); }, - + /** * 设置编辑器的源文档 * Set CodeMirror value - * + * * @param {String} value set code/value/string/text * @returns {editormd} 返回editormd的实例对象 */ - + setValue : function(value) { this.cm.setValue(value); - + return this; }, - + /** * 清空编辑器 * Empty CodeMirror editor container - * + * * @returns {editormd} 返回editormd的实例对象 */ - + clear : function() { this.cm.setValue(""); - + return this; }, - + /** * 获取解析后存放在Textarea的HTML源码 * Get parsed html code from Textarea - * + * * @returns {String} 返回HTML源码 */ - + getHTML : function() { if (!this.settings.saveHTMLToTextarea) { @@ -132441,28 +132463,28 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); return false; } - + return this.htmlTextarea.val(); }, - + /** * getHTML()的别名 * getHTML (alias) - * + * * @returns {String} Return html code 返回HTML源码 */ - + getTextareaSavedHTML : function() { return this.getHTML(); }, - + /** * 获取预览窗口的HTML源码 * Get html from preview container - * + * * @returns {editormd} 返回editormd的实例对象 */ - + getPreviewedHTML : function() { if (!this.settings.watch) { @@ -132470,137 +132492,137 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); return false; } - + return this.previewContainer.html(); }, - + /** * 开启实时预览 * Enable real-time watching - * + * * @returns {editormd} 返回editormd的实例对象 */ - - watch : function(callback) { + + watch : function(callback) { var settings = this.settings; - + if ($.inArray(settings.mode, ["gfm", "markdown"]) < 0) { return this; } - + this.state.watching = settings.watch = true; this.preview.show(); - + if (this.toolbar) { var watchIcon = settings.toolbarIconsClass.watch; var unWatchIcon = settings.toolbarIconsClass.unwatch; - + var icon = this.toolbar.find(".fa[name=watch]"); icon.parent().attr("title", settings.lang.toolbar.watch); icon.removeClass(unWatchIcon).addClass(watchIcon); } - - this.codeMirror.css("border-right", "1px solid #ddd").width(this.editor.width() / 2); - + + this.codeMirror.css("border-right", "1px solid #ddd").width(this.editor.width() / 2); + timer = 0; - + this.save().resize(); - + if (!settings.onwatch) { settings.onwatch = callback || function() {}; } - + $.proxy(settings.onwatch, this)(); - + return this; }, - + /** * 关闭实时预览 * Disable real-time watching - * + * * @returns {editormd} 返回editormd的实例对象 */ - + unwatch : function(callback) { var settings = this.settings; this.state.watching = settings.watch = false; this.preview.hide(); - - if (this.toolbar) + + if (this.toolbar) { var watchIcon = settings.toolbarIconsClass.watch; var unWatchIcon = settings.toolbarIconsClass.unwatch; - + var icon = this.toolbar.find(".fa[name=watch]"); icon.parent().attr("title", settings.lang.toolbar.unwatch); icon.removeClass(watchIcon).addClass(unWatchIcon); } - + this.codeMirror.css("border-right", "none").width(this.editor.width()); - + this.resize(); - + if (!settings.onunwatch) { settings.onunwatch = callback || function() {}; } - + $.proxy(settings.onunwatch, this)(); - + return this; }, - + /** * 显示编辑器 * Show editor - * + * * @param {Function} [callback=function()] 回调函数 * @returns {editormd} 返回editormd的实例对象 */ - + show : function(callback) { callback = callback || function() {}; - + var _this = this; this.editor.show(0, function() { $.proxy(callback, _this)(); }); - + return this; }, - + /** * 隐藏编辑器 * Hide editor - * + * * @param {Function} [callback=function()] 回调函数 * @returns {editormd} 返回editormd的实例对象 */ - + hide : function(callback) { callback = callback || function() {}; - + var _this = this; this.editor.hide(0, function() { $.proxy(callback, _this)(); }); - + return this; }, - + /** * 隐藏编辑器部分,只预览HTML * Enter preview html state - * + * * @returns {editormd} 返回editormd的实例对象 */ - + previewing : function() { - + var _this = this; var editor = this.editor; var preview = this.preview; @@ -132608,18 +132630,18 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); var settings = this.settings; var codeMirror = this.codeMirror; var previewContainer = this.previewContainer; - + if ($.inArray(settings.mode, ["gfm", "markdown"]) < 0) { return this; } - + if (settings.toolbar && toolbar) { toolbar.toggle(); toolbar.find(".fa[name=preview]").toggleClass("active"); } - + codeMirror.toggle(); - + var escHandle = function(event) { if (event.shiftKey && event.keyCode === 27) { _this.previewed(); @@ -132633,20 +132655,20 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); if (this.state.fullscreen) { preview.css("background", "#fff"); } - + editor.find("." + this.classPrefix + "preview-close-btn").show().bind(editormd.mouseOrTouch("click", "touchend"), function(){ _this.previewed(); }); - + if (!settings.watch) { this.save(); - } - else + } + else { previewContainer.css("padding", ""); } - + previewContainer.addClass(this.classPrefix + "preview-active"); preview.show().css({ @@ -132655,30 +132677,30 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); width : editor.width(), height : (settings.autoHeight && !this.state.fullscreen) ? "auto" : editor.height() }); - + if (this.state.loaded) { $.proxy(settings.onpreviewing, this)(); } $(window).bind("keyup", escHandle); - } - else + } + else { $(window).unbind("keyup", escHandle); this.previewed(); } }, - + /** * 显示编辑器部分,退出只预览HTML * Exit preview html state - * + * * @returns {editormd} 返回editormd的实例对象 */ - + previewed : function() { - + var editor = this.editor; var preview = this.preview; var toolbar = this.toolbar; @@ -132687,25 +132709,25 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); var previewCloseBtn = editor.find("." + this.classPrefix + "preview-close-btn"); this.state.preview = false; - + this.codeMirror.show(); - + if (settings.toolbar) { toolbar.show(); } - + preview[(settings.watch) ? "show" : "hide"](); - + previewCloseBtn.hide().unbind(editormd.mouseOrTouch("click", "touchend")); - + previewContainer.removeClass(this.classPrefix + "preview-active"); - + if (settings.watch) { previewContainer.css("padding", "20px"); } - - preview.css({ + + preview.css({ background : null, position : "absolute", width : editor.width() / 2, @@ -132717,19 +132739,19 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); { $.proxy(settings.onpreviewed, this)(); } - + return this; }, - + /** * 编辑器全屏显示 * Fullscreen show - * + * * @returns {editormd} 返回editormd的实例对象 */ - + fullscreen : function() { - + var _this = this; var state = this.state; var editor = this.editor; @@ -132737,13 +132759,13 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); var toolbar = this.toolbar; var settings = this.settings; var fullscreenClass = this.classPrefix + "fullscreen"; - + if (toolbar) { - toolbar.find(".fa[name=fullscreen]").parent().toggleClass("active"); + toolbar.find(".fa[name=fullscreen]").parent().toggleClass("active"); } - + var escHandle = function(event) { - if (!event.shiftKey && event.keyCode === 27) + if (!event.shiftKey && event.keyCode === 27) { if (state.fullscreen) { @@ -132752,50 +132774,50 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); } }; - if (!editor.hasClass(fullscreenClass)) + if (!editor.hasClass(fullscreenClass)) { state.fullscreen = true; $("html,body").css("overflow", "hidden"); - + editor.css({ width : $(window).width(), height : $(window).height() }).addClass(fullscreenClass); this.resize(); - + $.proxy(settings.onfullscreen, this)(); $(window).bind("keyup", escHandle); } else - { - $(window).unbind("keyup", escHandle); + { + $(window).unbind("keyup", escHandle); this.fullscreenExit(); } return this; }, - + /** * 编辑器退出全屏显示 * Exit fullscreen state - * + * * @returns {editormd} 返回editormd的实例对象 */ - + fullscreenExit : function() { - + var editor = this.editor; var settings = this.settings; var toolbar = this.toolbar; - var fullscreenClass = this.classPrefix + "fullscreen"; - + var fullscreenClass = this.classPrefix + "fullscreen"; + this.state.fullscreen = false; - + if (toolbar) { - toolbar.find(".fa[name=fullscreen]").parent().removeClass("active"); + toolbar.find(".fa[name=fullscreen]").parent().removeClass("active"); } $("html,body").css("overflow", ""); @@ -132806,43 +132828,43 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); }).removeClass(fullscreenClass); this.resize(); - + $.proxy(settings.onfullscreenExit, this)(); return this; }, - + /** * 加载并执行插件 * Load and execute the plugin - * + * * @param {String} name plugin name / function name * @param {String} path plugin load path * @returns {editormd} 返回editormd的实例对象 */ - + executePlugin : function(name, path) { - + var _this = this; var cm = this.cm; var settings = this.settings; - + path = settings.pluginPath + path; - - if (typeof define === "function") - { + + if (typeof define === "function") + { if (typeof this[name] === "undefined") { alert("Error: " + name + " plugin is not found, you are not load this plugin."); - + return this; } - + this[name](cm); - + return this; } - + if ($.inArray(path, editormd.loadFiles.plugin) < 0) { editormd.loadPlugin(path, function() { @@ -132854,79 +132876,79 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); { $.proxy(editormd.loadPlugins[name], this)(cm); } - + return this; }, - + /** * 搜索替换 * Search & replace - * + * * @param {String} command CodeMirror serach commands, "find, fintNext, fintPrev, clearSearch, replace, replaceAll" * @returns {editormd} return this */ - + search : function(command) { var settings = this.settings; - + if (!settings.searchReplace) { alert("Error: settings.searchReplace == false"); return this; } - + if (!settings.readOnly) { this.cm.execCommand(command || "find"); } - + return this; }, - - searchReplace : function() { + + searchReplace : function() { this.search("replace"); - + return this; }, - - searchReplaceAll : function() { + + searchReplaceAll : function() { this.search("replaceAll"); - + return this; } }; - - editormd.fn.init.prototype = editormd.fn; - + + editormd.fn.init.prototype = editormd.fn; + /** * 锁屏 * lock screen when dialog opening - * + * * @returns {void} */ editormd.dialogLockScreen = function() { var settings = this.settings || {dialogLockScreen : true}; - - if (settings.dialogLockScreen) - { + + if (settings.dialogLockScreen) + { $("html,body").css("overflow", "hidden"); this.resize(); } }; - + /** * 显示透明背景层 * Display mask layer when dialog opening - * + * * @param {Object} dialog dialog jQuery object * @returns {void} */ - + editormd.dialogShowMask = function(dialog) { var editor = this.editor; var settings = this.settings || {dialogShowMask : true}; - + dialog.css({ top : ($(window).height() - dialog.height()) / 2 + "px", left : ($(window).width() - dialog.width()) / 2 + "px" @@ -132941,11 +132963,11 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); undo : function() { this.cm.undo(); }, - + redo : function() { this.cm.redo(); }, - + bold : function() { var cm = this.cm; var cursor = cm.getCursor(); @@ -132957,7 +132979,7 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); cm.setCursor(cursor.line, cursor.ch + 2); } }, - + del : function() { var cm = this.cm; var cursor = cm.getCursor(); @@ -133001,7 +133023,7 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); //cm.replaceSelection("> " + selection); //cm.setCursor(cursor.line, (selection === "") ? cursor.ch + 2 : cursor.ch + selection.length + 2); }, - + ucfirst : function() { var cm = this.cm; var selection = cm.getSelection(); @@ -133010,7 +133032,7 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); cm.replaceSelection(editormd.firstUpperCase(selection)); cm.setSelections(selections); }, - + ucwords : function() { var cm = this.cm; var selection = cm.getSelection(); @@ -133019,7 +133041,7 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); cm.replaceSelection(editormd.wordsFirstUpperCase(selection)); cm.setSelections(selections); }, - + uppercase : function() { var cm = this.cm; var selection = cm.getSelection(); @@ -133028,13 +133050,13 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); cm.replaceSelection(selection.toUpperCase()); cm.setSelections(selections); }, - + lowercase : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); var selections = cm.listSelections(); - + cm.replaceSelection(selection.toLowerCase()); cm.setSelections(selections); }, @@ -133146,15 +133168,15 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); var cursor = cm.getCursor(); var selection = cm.getSelection(); - if (selection === "") + if (selection === "") { cm.replaceSelection("- " + selection); - } - else + } + else { var selectionText = selection.split("\n"); - for (var i = 0, len = selectionText.length; i < len; i++) + for (var i = 0, len = selectionText.length; i < len; i++) { selectionText[i] = (selectionText[i] === "") ? "" : "- " + selectionText[i]; } @@ -133168,7 +133190,7 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); var cursor = cm.getCursor(); var selection = cm.getSelection(); - if(selection === "") + if(selection === "") { cm.replaceSelection("1. " + selection); } @@ -133176,7 +133198,7 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); { var selectionText = selection.split("\n"); - for (var i = 0, len = selectionText.length; i < len; i++) + for (var i = 0, len = selectionText.length; i < len; i++) { selectionText[i] = (selectionText[i] === "") ? "" : (i+1) + ". " + selectionText[i]; } @@ -133199,7 +133221,7 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); alert("settings.tex === false"); return this; } - + var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); @@ -133225,7 +133247,7 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); alert("settings.pageBreak === false"); return this; } - + var cm = this.cm; var selection = cm.getSelection(); @@ -133235,7 +133257,7 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); image : function() { this.executePlugin("imageDialog", "image-dialog/image-dialog"); }, - + code : function() { var cm = this.cm; var cursor = cm.getCursor(); @@ -133249,17 +133271,17 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); }, "code-block" : function() { - this.executePlugin("codeBlockDialog", "code-block-dialog/code-block-dialog"); + this.executePlugin("codeBlockDialog", "code-block-dialog/code-block-dialog"); }, "preformatted-text" : function() { this.executePlugin("preformattedTextDialog", "preformatted-text-dialog/preformatted-text-dialog"); }, - + table : function() { - this.executePlugin("tableDialog", "table-dialog/table-dialog"); + this.executePlugin("tableDialog", "table-dialog/table-dialog"); }, - + datetime : function() { var cm = this.cm; var selection = cm.getSelection(); @@ -133269,20 +133291,20 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); cm.replaceSelection(datefmt); }, - + emoji : function() { this.executePlugin("emojiDialog", "emoji-dialog/emoji-dialog"); }, - + "html-entities" : function() { this.executePlugin("htmlEntitiesDialog", "html-entities-dialog/html-entities-dialog"); }, - + "goto-line" : function() { this.executePlugin("gotoLineDialog", "goto-line-dialog/goto-line-dialog"); }, - watch : function() { + watch : function() { this[this.settings.watch ? "unwatch" : "watch"](); }, @@ -133297,7 +133319,7 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); clear : function() { this.clear(); }, - + search : function() { this.search(); }, @@ -133310,7 +133332,7 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); this.showInfoDialog(); } }; - + editormd.keyMaps = { "Ctrl-1" : "h1", "Ctrl-2" : "h2", @@ -133320,12 +133342,12 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); "Ctrl-6" : "h6", "Ctrl-B" : "bold", // if this is string == editormd.toolbarHandlers.xxxx "Ctrl-D" : "datetime", - + "Ctrl-E" : function() { // emoji var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); - + if (!this.settings.emoji) { alert("Error: settings.emoji == false"); @@ -133342,12 +133364,12 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); "Ctrl-H" : "hr", "Ctrl-I" : "italic", "Ctrl-K" : "code", - + "Ctrl-L" : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); - + var title = (selection === "") ? "" : " \""+selection+"\""; cm.replaceSelection("[" + selection + "]("+title+")"); @@ -133357,12 +133379,12 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); } }, "Ctrl-U" : "list-ul", - + "Shift-Ctrl-A" : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); - + if (!this.settings.atLink) { alert("Error: settings.atLink == false"); @@ -133375,24 +133397,24 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); cm.setCursor(cursor.line, cursor.ch + 1); } }, - + "Shift-Ctrl-C" : "code", "Shift-Ctrl-Q" : "quote", "Shift-Ctrl-S" : "del", "Shift-Ctrl-K" : "tex", // KaTeX - + "Shift-Alt-C" : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); - + cm.replaceSelection(["```", selection, "```"].join("\n")); if (selection === "") { cm.setCursor(cursor.line, cursor.ch + 3); - } + } }, - + "Shift-Ctrl-Alt-C" : "code-block", "Shift-Ctrl-H" : "html-entities", "Shift-Alt-H" : "help", @@ -133401,12 +133423,12 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); "Shift-Alt-U" : "ucwords", "Shift-Ctrl-Alt-U" : "ucfirst", "Shift-Alt-L" : "lowercase", - + "Shift-Ctrl-I" : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); - + var title = (selection === "") ? "" : " \""+selection+"\""; cm.replaceSelection("![" + selection + "]("+title+")"); @@ -133415,7 +133437,7 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); cm.setCursor(cursor.line, cursor.ch + 4); } }, - + "Shift-Ctrl-Alt-I" : "image", "Shift-Ctrl-L" : "link", "Shift-Ctrl-O" : "list-ol", @@ -133426,59 +133448,59 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); "F10" : "preview", "F11" : "fullscreen", }; - + /** * 清除字符串两边的空格 * Clear the space of strings both sides. - * + * * @param {String} str string - * @returns {String} trimed string + * @returns {String} trimed string */ - + var trim = function(str) { return (!String.prototype.trim) ? str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, "") : str.trim(); }; - + editormd.trim = trim; - + /** * 所有单词首字母大写 * Words first to uppercase - * + * * @param {String} str string * @returns {String} string */ - + var ucwords = function (str) { - return str.toLowerCase().replace(/\b(\w)|\s(\w)/g, function($1) { + return str.toLowerCase().replace(/\b(\w)|\s(\w)/g, function($1) { return $1.toUpperCase(); }); }; - + editormd.ucwords = editormd.wordsFirstUpperCase = ucwords; - + /** * 字符串首字母大写 * Only string first char to uppercase - * + * * @param {String} str string * @returns {String} string */ - - var firstUpperCase = function(str) { + + var firstUpperCase = function(str) { return str.toLowerCase().replace(/\b(\w)/, function($1){ return $1.toUpperCase(); }); }; - + var ucfirst = firstUpperCase; - + editormd.firstUpperCase = editormd.ucfirst = firstUpperCase; - + editormd.urls = { atLinkBase : "https://github.com/" }; - + editormd.regexs = { atLink : /@(\w+)/g, email : /(\w+)@(\w+)\.(\w+)\.?(\w+)?/g, @@ -133497,7 +133519,7 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); ext : ".png" }; - // Twitter Emoji (Twemoji) graphics files url path + // Twitter Emoji (Twemoji) graphics files url path editormd.twemoji = { path : "http://twemoji.maxcdn.com/36x36/", ext : ".png" @@ -133506,7 +133528,7 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); /** * 自定义marked的解析器 * Custom Marked renderer rules - * + * * @param {Array} markdownToC 传入用于接收TOC的数组 * @returns {Renderer} markedRenderer 返回marked的Renderer自定义对象 */ @@ -133515,7 +133537,7 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); var defaults = { toc : true, // Table of contents tocm : false, - tocStartLevel : 1, // Said from H1 to create ToC + tocStartLevel : 1, // Said from H1 to create ToC pageBreak : true, atLink : true, // for @link emailLink : true, // for mail address auto link @@ -133525,12 +133547,12 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); flowChart : false, // flowChart.js only support IE9+ sequenceDiagram : false, // sequenceDiagram.js only support IE9+ }; - - var settings = $.extend(defaults, options || {}); + + var settings = $.extend(defaults, options || {}); var marked = editormd.$marked; var markedRenderer = new marked.Renderer(); - markdownToC = markdownToC || []; - + markdownToC = markdownToC || []; + var regexs = editormd.regexs; var atLinkReg = regexs.atLink; var emojiReg = regexs.emoji; @@ -133542,11 +133564,11 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); var pageBreakReg = regexs.pageBreak; markedRenderer.emoji = function(text) { - - text = text.replace(editormd.regexs.emojiDatetime, function($1) { + + text = text.replace(editormd.regexs.emojiDatetime, function($1) { return $1.replace(/:/g, ":"); }); - + var matchs = text.match(emojiReg); if (!matchs || !settings.emoji) { @@ -133554,7 +133576,7 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); } for (var i = 0, len = matchs.length; i < len; i++) - { + { if (matchs[i] === ":+1:") { matchs[i] = ":\\+1:"; } @@ -133564,11 +133586,11 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); var name = $1.replace(/:/g, ""); if (faMatchs) - { + { for (var fa = 0, len1 = faMatchs.length; fa < len1; fa++) { var faName = faMatchs[fa].replace(/:/g, ""); - + return ""; } } @@ -133577,15 +133599,15 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); var emdlogoMathcs = $1.match(editormdLogoReg); var twemojiMatchs = $1.match(twemojiReg); - if (emdlogoMathcs) - { + if (emdlogoMathcs) + { for (var x = 0, len2 = emdlogoMathcs.length; x < len2; x++) { var logoName = emdlogoMathcs[x].replace(/:/g, ""); return ""; } } - else if (twemojiMatchs) + else if (twemojiMatchs) { for (var t = 0, len3 = twemojiMatchs.length; t < len3; t++) { @@ -133611,8 +133633,8 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); markedRenderer.atLink = function(text) { if (atLinkReg.test(text)) - { - if (settings.atLink) + { + if (settings.atLink) { text = text.replace(emailReg, function($1, $2, $3, $4) { return $1.replace(/@/g, "_#_@_#_"); @@ -133622,7 +133644,7 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); return "" + $1 + ""; }).replace(/_#_@_#_/g, "@"); } - + if (settings.emailLink) { text = text.replace(emailLinkReg, function($1, $2, $3, $4, $5) { @@ -133635,7 +133657,7 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); return text; }; - + markedRenderer.link = function (href, title, text) { if (this.options.sanitize) { @@ -133651,14 +133673,14 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); } var out = "" + text.replace(/@/g, "@") + ""; } @@ -133670,14 +133692,14 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); return out; }; - + markedRenderer.heading = function(text, level, raw) { - + var linkText = text; var hasLinkReg = /\s*\]*)\>(.*)\<\/a\>\s*/; var getLinkTextReg = /\s*\]+)\>([^\>]*)\<\/a\>\s*/g; - if (hasLinkReg.test(text)) + if (hasLinkReg.test(text)) { var tempText = []; text = text.split(/\]+)\>([^\>]*)\<\/a\>/); @@ -133689,23 +133711,23 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); text = tempText.join(" "); } - + text = trim(text); - + var escapedText = text.toLowerCase().replace(/[^\w]+/g, "-"); var toc = { text : text, level : level, slug : escapedText }; - + var isChinese = /^[\u4e00-\u9fa5]+$/.test(text); var id = (isChinese) ? escape(text).replace(/\%/g, "") : text.toLowerCase().replace(/[^\w]+/g, "-"); markdownToC.push(toc); - + var headingHTML = ""; - + headingHTML += ""; headingHTML += ""; headingHTML += (hasLinkReg) ? this.atLink(this.emoji(linkText)) : this.atLink(this.emoji(text)); @@ -133713,13 +133735,13 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); return headingHTML; }; - + markedRenderer.pageBreak = function(text) { if (pageBreakReg.test(text) && settings.pageBreak) { text = "
      "; } - + return text; }; @@ -133729,39 +133751,39 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); var isTeXAddClass = (isTeXLine) ? " class=\"" + editormd.classNames.tex + "\"" : ""; var isToC = (settings.tocm) ? /^(\[TOC\]|\[TOCM\])$/.test(text) : /^\[TOC\]$/.test(text); var isToCMenu = /^\[TOCM\]$/.test(text); - - if (!isTeXLine && isTeXInline) + + if (!isTeXLine && isTeXInline) { text = text.replace(/(\$\$([^\$]*)\$\$)+/g, function($1, $2) { return "" + $2.replace(/\$/g, "") + ""; }); - } - else + } + else { text = (isTeXLine) ? text.replace(/\$/g, "") : text; } - + var tocHTML = "
      " + text + "
      "; - + return (isToC) ? ( (isToCMenu) ? "
      " + tocHTML + "

      " : tocHTML ) : ( (pageBreakReg.test(text)) ? this.pageBreak(text) : "" + this.atLink(this.emoji(text)) + "

      \n" ); }; - markedRenderer.code = function (code, lang, escaped) { + markedRenderer.code = function (code, lang, escaped) { if (lang === "seq" || lang === "sequence") { return "
      " + code + "
      "; - } + } else if ( lang === "flow") { return "
      " + code + "
      "; - } + } else if ( lang === "math" || lang === "latex" || lang === "katex") { return "

      " + code + "

      "; - } - else + } + else { return marked.Renderer.prototype.code.apply(this, arguments); @@ -133771,64 +133793,64 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); markedRenderer.tablecell = function(content, flags) { var type = (flags.header) ? "th" : "td"; var tag = (flags.align) ? "<" + type +" style=\"text-align:" + flags.align + "\">" : "<" + type + ">"; - + return tag + this.atLink(this.emoji(content)) + "\n"; }; markedRenderer.listitem = function(text) { - if (settings.taskList && /^\s*\[[x\s]\]\s*/.test(text)) + if (settings.taskList && /^\s*\[[x\s]\]\s*/.test(text)) { text = text.replace(/^\s*\[\s\]\s*/, " ") .replace(/^\s*\[x\]\s*/, " "); return "
    • " + this.atLink(this.emoji(text)) + "
    • "; } - else + else { return "
    • " + this.atLink(this.emoji(text)) + "
    • "; } }; - + return markedRenderer; }; - + /** * * 生成TOC(Table of Contents) * Creating ToC (Table of Contents) - * + * * @param {Array} toc 从marked获取的TOC数组列表 * @param {Element} container 插入TOC的容器元素 * @param {Integer} startLevel Hx 起始层级 * @returns {Object} tocContainer 返回ToC列表容器层的jQuery对象元素 */ - + editormd.markdownToCRenderer = function(toc, container, tocDropdown, startLevel) { - - var html = ""; + + var html = ""; var lastLevel = 0; var classPrefix = this.classPrefix; - + startLevel = startLevel || 1; - - for (var i = 0, len = toc.length; i < len; i++) + + for (var i = 0, len = toc.length; i < len; i++) { var text = toc[i].text; var level = toc[i].level; - + if (level < startLevel) { continue; } - - if (level > lastLevel) + + if (level > lastLevel) { html += ""; } - else if (level < lastLevel) + else if (level < lastLevel) { html += (new Array(lastLevel - level + 2)).join(""); - } - else + } + else { html += ""; } @@ -133836,44 +133858,44 @@ CodeMirror.defineMIME('application/x-sh', 'shell'); html += "
    • " + text + "