diff --git a/go.mod b/go.mod
index 387a34520..e07defe79 100755
--- a/go.mod
+++ b/go.mod
@@ -120,7 +120,7 @@ require (
github.com/urfave/cli v1.22.1
github.com/xanzy/go-gitlab v0.31.0
github.com/yohcop/openid-go v1.0.0
- github.com/yuin/goldmark v1.1.30
+ github.com/yuin/goldmark v1.4.13
github.com/yuin/goldmark-meta v0.0.0-20191126180153-f0638e958b60
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37
golang.org/x/mod v0.3.0 // indirect
diff --git a/go.sum b/go.sum
index d55d7af48..bd231b321 100755
--- a/go.sum
+++ b/go.sum
@@ -804,6 +804,8 @@ github.com/yuin/goldmark v1.1.27 h1:nqDD4MMMQA0lmWq03Z2/myGPYLQoXtmi0rGVs95ntbo=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.30 h1:j4d4Lw3zqZelDhBksEo3BnWg9xhXRQGJPPSL6OApZjI=
github.com/yuin/goldmark v1.1.30/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yuin/goldmark-meta v0.0.0-20191126180153-f0638e958b60 h1:gZucqLjL1eDzVWrXj4uiWeMbAopJlBR2mKQAsTGdPwo=
github.com/yuin/goldmark-meta v0.0.0-20191126180153-f0638e958b60/go.mod h1:i9VhcIHN2PxXMbQrKqXNueok6QNONoPjNMoj9MygVL0=
github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
diff --git a/models/cloudbrain.go b/models/cloudbrain.go
index 5091a8762..f9897b91d 100755
--- a/models/cloudbrain.go
+++ b/models/cloudbrain.go
@@ -1680,21 +1680,6 @@ func GetCloudbrainsNeededStopByUserID(userID int64) ([]*Cloudbrain, error) {
return cloudBrains, err
}
-func GetWaittingTop() ([]*CloudbrainInfo, error) {
- sess := x.NewSession()
- defer sess.Close()
- var cond = builder.NewCond()
- cond = cond.And(
- builder.Eq{"cloudbrain.status": string(JobWaiting)},
- )
- sess.OrderBy("cloudbrain.created_unix ASC limit 1")
- cloudbrains := make([]*CloudbrainInfo, 0, 1)
- if err := sess.Table(&Cloudbrain{}).Where(cond).
- Find(&cloudbrains); err != nil {
- log.Info("find error.")
- }
- return cloudbrains, nil
-}
func GetModelartsReDebugTaskByJobId(jobID string) ([]*Cloudbrain, error) {
sess := x.NewSession()
defer sess.Close()
diff --git a/models/cloudbrain_static.go b/models/cloudbrain_static.go
index e3ac5e963..371b30f66 100644
--- a/models/cloudbrain_static.go
+++ b/models/cloudbrain_static.go
@@ -36,133 +36,6 @@ type TaskDetail struct {
FlavorName string `json:"FlavorName"`
}
-func GetDebugOnePeriodCount(beginTime time.Time, endTime time.Time) (int64, error) {
- countSql := "SELECT count(*) FROM " +
- "public.cloudbrain where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) +
- " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) +
- " and job_type ='" + string(JobTypeDebug) + "'" +
- " and type='" + strconv.Itoa(TypeCloudBrainOne) + "'"
-
- return x.SQL(countSql).Count()
-}
-func GetDebugOnePeriodDuration(beginTime time.Time, endTime time.Time) (int64, error) {
- total, err := x.Where("created_unix >= ? And created_unix < ? And job_type = ? And type = ? ", strconv.FormatInt(beginTime.Unix(), 10), strconv.FormatInt(endTime.Unix(), 10), JobTypeDebug, TypeCloudBrainOne).SumInt(&Cloudbrain{}, "duration")
- if err != nil {
- return 0, err
- }
-
- return total, nil
-}
-
-func GetTrainOnePeriodCount(beginTime time.Time, endTime time.Time) (int64, error) {
- countSql := "SELECT count(*) FROM " +
- "public.cloudbrain where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) +
- " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) +
- " and job_type ='" + string(JobTypeTrain) + "'" +
- " and type='" + strconv.Itoa(TypeCloudBrainOne) + "'"
-
- return x.SQL(countSql).Count()
-}
-func GetTrainOnePeriodDuration(beginTime time.Time, endTime time.Time) (int64, error) {
- total, err := x.Where("created_unix >= ? And created_unix < ? And job_type = ? And type = ? ", strconv.FormatInt(beginTime.Unix(), 10), strconv.FormatInt(endTime.Unix(), 10), JobTypeTrain, TypeCloudBrainOne).SumInt(&Cloudbrain{}, "duration")
- if err != nil {
- return 0, err
- }
-
- return total, nil
-}
-
-func GetBenchmarkOnePeriodCount(beginTime time.Time, endTime time.Time) (int64, error) {
- countSql := "SELECT count(*) FROM " +
- "public.cloudbrain where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) +
- " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) +
- " and job_type ='" + string(JobTypeBenchmark) + "'" +
- " and type='" + strconv.Itoa(TypeCloudBrainOne) + "'"
- return x.SQL(countSql).Count()
-}
-func GetBenchmarkOnePeriodDuration(beginTime time.Time, endTime time.Time) (int64, error) {
- total, err := x.Where("created_unix >= ? And created_unix < ? And job_type = ? And type = ? ", strconv.FormatInt(beginTime.Unix(), 10), strconv.FormatInt(endTime.Unix(), 10), JobTypeBenchmark, TypeCloudBrainOne).SumInt(&Cloudbrain{}, "duration")
- if err != nil {
- return 0, err
- }
-
- return total, nil
-}
-func GetDebugTwoPeriodCount(beginTime time.Time, endTime time.Time) (int64, error) {
- countSql := "SELECT count(*) FROM " +
- "public.cloudbrain where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) +
- " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) +
- " and job_type ='" + string(JobTypeDebug) + "'" +
- " and type='" + strconv.Itoa(TypeCloudBrainTwo) + "'"
- return x.SQL(countSql).Count()
-}
-func GetDebugTwoPeriodDuration(beginTime time.Time, endTime time.Time) (int64, error) {
- total, err := x.Where("created_unix >= ? And created_unix < ? And job_type = ? And type = ? ", strconv.FormatInt(beginTime.Unix(), 10), strconv.FormatInt(endTime.Unix(), 10), JobTypeDebug, TypeCloudBrainTwo).SumInt(&Cloudbrain{}, "duration")
- if err != nil {
- return 0, err
- }
- return total, nil
-}
-func GetTrainTwoPeriodCount(beginTime time.Time, endTime time.Time) (int64, error) {
- countSql := "SELECT count(*) FROM " +
- "public.cloudbrain where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) +
- " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) +
- " and job_type ='" + string(JobTypeTrain) + "'" +
- " and type='" + strconv.Itoa(TypeCloudBrainTwo) + "'"
- return x.SQL(countSql).Count()
-}
-func GetTrainTwoPeriodDuration(beginTime time.Time, endTime time.Time) (int64, error) {
- total, err := x.Where("created_unix >= ? And created_unix < ? And job_type = ? And type = ? ", strconv.FormatInt(beginTime.Unix(), 10), strconv.FormatInt(endTime.Unix(), 10), JobTypeTrain, TypeCloudBrainTwo).SumInt(&Cloudbrain{}, "duration")
- if err != nil {
- return 0, err
- }
- return total, nil
-}
-func GetInferenceTwoPeriodCount(beginTime time.Time, endTime time.Time) (int64, error) {
- countSql := "SELECT count(*) FROM " +
- "public.cloudbrain where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) +
- " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) +
- " and job_type ='" + string(JobTypeInference) + "'" +
- " and type='" + strconv.Itoa(TypeCloudBrainTwo) + "'"
- return x.SQL(countSql).Count()
-}
-func GetInferenceTwoPeriodDuration(beginTime time.Time, endTime time.Time) (int64, error) {
- total, err := x.Where("created_unix >= ? And created_unix < ? And job_type = ? And type = ? ", strconv.FormatInt(beginTime.Unix(), 10), strconv.FormatInt(endTime.Unix(), 10), JobTypeInference, TypeCloudBrainTwo).SumInt(&Cloudbrain{}, "duration")
- if err != nil {
- return 0, err
- }
- return total, nil
-}
-
-func GetCloudBrainOnePeriodCount(beginTime time.Time, endTime time.Time) (int64, error) {
- countSql := "SELECT count(*) FROM " +
- "public.cloudbrain where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) +
- " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) +
- " and type='" + strconv.Itoa(TypeCloudBrainOne) + "'"
- return x.SQL(countSql).Count()
-}
-func GetCloudBrainOnePeriodDuration(beginTime time.Time, endTime time.Time) (int64, error) {
- total, err := x.Where("created_unix >= ? And created_unix < ? And type = ? ", strconv.FormatInt(beginTime.Unix(), 10), strconv.FormatInt(endTime.Unix(), 10), TypeCloudBrainOne).SumInt(&Cloudbrain{}, "duration")
- if err != nil {
- return 0, err
- }
- return total, nil
-}
-func GetCloudBrainTwoPeriodCount(beginTime time.Time, endTime time.Time) (int64, error) {
- countSql := "SELECT count(*) FROM " +
- "public.cloudbrain where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) +
- " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) +
- " and type='" + strconv.Itoa(TypeCloudBrainTwo) + "'"
- return x.SQL(countSql).Count()
-}
-func GetCloudBrainTwoPeriodDuration(beginTime time.Time, endTime time.Time) (int64, error) {
- total, err := x.Where("created_unix >= ? And created_unix < ? And type = ? ", strconv.FormatInt(beginTime.Unix(), 10), strconv.FormatInt(endTime.Unix(), 10), TypeCloudBrainTwo).SumInt(&Cloudbrain{}, "duration")
- if err != nil {
- return 0, err
- }
- return total, nil
-}
-
func GetTodayCreatorCount(beginTime time.Time, endTime time.Time) (int64, error) {
countSql := "SELECT count(distinct user_id) FROM " +
"public.cloudbrain where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) +
@@ -211,6 +84,22 @@ func GetAllStatusCloudBrain() map[string]int {
return cloudBrainStatusResult
}
+func GetWaittingTop() ([]*CloudbrainInfo, error) {
+ sess := x.NewSession()
+ defer sess.Close()
+ var cond = builder.NewCond()
+ cond = cond.And(
+ builder.Eq{"cloudbrain.status": string(JobWaiting)},
+ )
+ sess.OrderBy("cloudbrain.created_unix ASC limit 10")
+ cloudbrains := make([]*CloudbrainInfo, 0, 10)
+ if err := sess.Table(&Cloudbrain{}).Where(cond).
+ Find(&cloudbrains); err != nil {
+ log.Info("find error.")
+ }
+ return cloudbrains, nil
+}
+
func GetRunningTop() ([]*CloudbrainInfo, error) {
sess := x.NewSession()
defer sess.Close()
diff --git a/models/repo.go b/models/repo.go
index feb6fd3ef..5e11df2b6 100755
--- a/models/repo.go
+++ b/models/repo.go
@@ -2250,6 +2250,18 @@ func CheckRepoStats(ctx context.Context) error {
"UPDATE `repository` SET num_stars=(SELECT COUNT(*) FROM `star` WHERE repo_id=?) WHERE id=?",
"repository count 'num_stars'",
},
+ //Repository.NumIssues
+ {
+ "SELECT repo.id FROM `repository` repo WHERE repo.num_issues!=(SELECT COUNT(*) FROM `issue` WHERE repo_id=repo.id AND is_pull=false)",
+ "UPDATE `repository` SET num_issues=(SELECT COUNT(*) FROM `issue` WHERE repo_id=? AND is_pull=false) WHERE id=?",
+ "repository count 'num_issues'",
+ },
+ //Repository.NumPulls
+ {
+ "SELECT repo.id FROM `repository` repo WHERE repo.num_pulls!=(SELECT COUNT(*) FROM `issue` WHERE repo_id=repo.id AND is_pull=true)",
+ "UPDATE `repository` SET num_pulls=(SELECT COUNT(*) FROM `issue` WHERE repo_id=? AND is_pull=true) WHERE id=?",
+ "repository count 'num_pulls'",
+ },
// Label.NumIssues
{
"SELECT label.id FROM `label` WHERE label.num_issues!=(SELECT COUNT(*) FROM `issue_label` WHERE label_id=label.id)",
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index 1b9498f71..d1e61d242 100755
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -3141,5 +3141,6 @@ Not_Stopped=The job is not stopped, can not be deleted.
Already_stopped=The job is already stopped.
Stopped_failed=Fail to stop the job, please try again later.
Stopped_success_update_status_fail=Succeed in stopping th job, but failed to update the job status and duration time.
+load_code_failed=Fail to load code, please check if the right branch is selected.
error.dataset_select = dataset select error:the count exceed the limit or has same name
diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini
index 71520f765..a39118c0a 100755
--- a/options/locale/locale_zh-CN.ini
+++ b/options/locale/locale_zh-CN.ini
@@ -3156,6 +3156,7 @@ Not_Stopped=任务还未终止,不能删除。
Already_stopped=任务已停止。
Stopped_failed=任务停止失败,请稍后再试。
Stopped_success_update_status_fail=任务停止成功,状态及运行时间更新失败。
+load_code_failed=代码加载失败,请确认选择了正确的分支。
error.dataset_select = 数据集选择错误:数量超过限制或者有同名数据集
diff --git a/routers/repo/cloudbrain.go b/routers/repo/cloudbrain.go
index 15c7a26fe..76bf9b076 100755
--- a/routers/repo/cloudbrain.go
+++ b/routers/repo/cloudbrain.go
@@ -328,12 +328,12 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) {
if branchName == "" {
branchName = cloudbrain.DefaultBranchName
}
- downloadCode(repo, codePath, branchName)
- uploadCodeToMinio(codePath+"/", jobName, cloudbrain.CodeMountPath+"/")
-
- modelPath := setting.JobPath + jobName + cloudbrain.ModelMountPath + "/"
- mkModelPath(modelPath)
- uploadCodeToMinio(modelPath, jobName, cloudbrain.ModelMountPath+"/")
+ errStr = loadCodeAndMakeModelPath(repo, codePath, branchName, jobName, cloudbrain.ModelMountPath)
+ if errStr != "" {
+ cloudBrainNewDataPrepare(ctx)
+ ctx.RenderWithErr(ctx.Tr(errStr), tpl, &form)
+ return
+ }
commitID, _ := ctx.Repo.GitRepo.GetBranchCommitID(branchName)
@@ -378,6 +378,30 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) {
}
}
+func loadCodeAndMakeModelPath(repo *models.Repository, codePath string, branchName string, jobName string, resultPath string) string {
+ err := downloadCode(repo, codePath, branchName)
+ if err != nil {
+ return "cloudbrain.load_code_failed"
+ }
+
+ err = uploadCodeToMinio(codePath+"/", jobName, cloudbrain.CodeMountPath+"/")
+ if err != nil {
+ return "cloudbrain.load_code_failed"
+ }
+
+ modelPath := setting.JobPath + jobName + resultPath + "/"
+ err = mkModelPath(modelPath)
+ if err != nil {
+ return "cloudbrain.load_code_failed"
+ }
+ err = uploadCodeToMinio(modelPath, jobName, resultPath+"/")
+ if err != nil {
+ return "cloudbrain.load_code_failed"
+ }
+
+ return ""
+}
+
func CloudBrainInferenceJobCreate(ctx *context.Context, form auth.CreateCloudBrainInferencForm) {
ctx.Data["PageIsCloudBrain"] = true
displayJobName := form.DisplayJobName
@@ -444,11 +468,12 @@ func CloudBrainInferenceJobCreate(ctx *context.Context, form auth.CreateCloudBra
if branchName == "" {
branchName = cloudbrain.DefaultBranchName
}
- downloadCode(repo, codePath, branchName)
- uploadCodeToMinio(codePath+"/", jobName, cloudbrain.CodeMountPath+"/")
- resultPath := setting.JobPath + jobName + cloudbrain.ResultPath + "/"
- mkResultPath(resultPath)
- uploadCodeToMinio(resultPath, jobName, cloudbrain.ResultPath+"/")
+ errStr := loadCodeAndMakeModelPath(repo, codePath, branchName, jobName, cloudbrain.ResultPath)
+ if errStr != "" {
+ cloudBrainNewDataPrepare(ctx)
+ ctx.RenderWithErr(ctx.Tr(errStr), tpl, &form)
+ return
+ }
commitID, _ := ctx.Repo.GitRepo.GetBranchCommitID(branchName)
@@ -1664,11 +1689,7 @@ func uploadCodeToMinio(codePath, jobName, parentDir string) error {
}
func mkModelPath(modelPath string) error {
- return mkPathAndReadMeFile(modelPath, "You can put the model file into this directory and download it by the web page.")
-}
-
-func mkResultPath(resultPath string) error {
- return mkPathAndReadMeFile(resultPath, "You can put the result file into this directory and download it by the web page.")
+ return mkPathAndReadMeFile(modelPath, "You can put the files into this directory and download the files by the web page.")
}
func mkPathAndReadMeFile(path string, text string) error {
diff --git a/routers/repo/grampus.go b/routers/repo/grampus.go
index 65dcbcb11..a05fae40c 100755
--- a/routers/repo/grampus.go
+++ b/routers/repo/grampus.go
@@ -45,8 +45,7 @@ func GrampusTrainJobGPUNew(ctx *context.Context) {
ctx.ServerError("get new train-job info failed", err)
return
}
- waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeC2Net, models.GPUResource, models.JobTypeTrain)
- ctx.Data["WaitCount"] = waitCount
+
ctx.HTML(http.StatusOK, tplGrampusTrainJobGPUNew)
}
@@ -57,8 +56,6 @@ func GrampusTrainJobNPUNew(ctx *context.Context) {
ctx.ServerError("get new train-job info failed", err)
return
}
- waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeC2Net, models.NPUResource, models.JobTypeTrain)
- ctx.Data["WaitCount"] = waitCount
ctx.HTML(200, tplGrampusTrainJobNPUNew)
}
@@ -131,8 +128,12 @@ func grampusTrainJobNewDataPrepare(ctx *context.Context, processType string) err
if processType == grampus.ProcessorTypeGPU {
ctx.Data["datasetType"] = models.TypeCloudBrainOne
+ waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeC2Net, models.GPUResource, models.JobTypeTrain)
+ ctx.Data["WaitCount"] = waitCount
} else if processType == grampus.ProcessorTypeNPU {
ctx.Data["datasetType"] = models.TypeCloudBrainTwo
+ waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeC2Net, models.NPUResource, models.JobTypeTrain)
+ ctx.Data["WaitCount"] = waitCount
}
return nil
@@ -280,7 +281,7 @@ func GrampusTrainJobGpuCreate(ctx *context.Context, form auth.CreateGrampusTrain
if err := downloadZipCode(ctx, codeLocalPath, branchName); err != nil {
log.Error("downloadZipCode failed, server timed out: %s (%v)", repo.FullName(), err, ctx.Data["MsgID"])
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU)
- ctx.RenderWithErr("Create task failed, internal error", tplGrampusTrainJobGPUNew, &form)
+ ctx.RenderWithErr(ctx.Tr("cloudbrain.load_code_failed"), tplGrampusTrainJobGPUNew, &form)
return
}
@@ -289,7 +290,7 @@ func GrampusTrainJobGpuCreate(ctx *context.Context, form auth.CreateGrampusTrain
if err := uploadCodeToMinio(codeLocalPath+"/", jobName, cloudbrain.CodeMountPath+"/"); err != nil {
log.Error("Failed to uploadCodeToMinio: %s (%v)", repo.FullName(), err, ctx.Data["MsgID"])
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU)
- ctx.RenderWithErr("Create task failed, internal error", tplGrampusTrainJobGPUNew, &form)
+ ctx.RenderWithErr(ctx.Tr("cloudbrain.load_code_failed"), tplGrampusTrainJobGPUNew, &form)
return
}
@@ -297,7 +298,7 @@ func GrampusTrainJobGpuCreate(ctx *context.Context, form auth.CreateGrampusTrain
if err := mkModelPath(modelPath); err != nil {
log.Error("Failed to mkModelPath: %s (%v)", repo.FullName(), err, ctx.Data["MsgID"])
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU)
- ctx.RenderWithErr("Create task failed, internal error", tplGrampusTrainJobGPUNew, &form)
+ ctx.RenderWithErr(ctx.Tr("cloudbrain.load_code_failed"), tplGrampusTrainJobGPUNew, &form)
return
}
@@ -305,7 +306,7 @@ func GrampusTrainJobGpuCreate(ctx *context.Context, form auth.CreateGrampusTrain
if err := uploadCodeToMinio(modelPath, jobName, cloudbrain.ModelMountPath+"/"); err != nil {
log.Error("Failed to uploadCodeToMinio: %s (%v)", repo.FullName(), err, ctx.Data["MsgID"])
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU)
- ctx.RenderWithErr("Create task failed, internal error", tplGrampusTrainJobGPUNew, &form)
+ ctx.RenderWithErr(ctx.Tr("cloudbrain.load_code_failed"), tplGrampusTrainJobGPUNew, &form)
return
}
@@ -464,22 +465,22 @@ func GrampusTrainJobNpuCreate(ctx *context.Context, form auth.CreateGrampusTrain
if err := downloadZipCode(ctx, codeLocalPath, branchName); err != nil {
log.Error("downloadZipCode failed, server timed out: %s (%v)", repo.FullName(), err)
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU)
- ctx.RenderWithErr("Create task failed, server timed out", tplGrampusTrainJobNPUNew, &form)
+ ctx.RenderWithErr(ctx.Tr("cloudbrain.load_code_failed"), tplGrampusTrainJobNPUNew, &form)
return
}
//todo: upload code (send to file_server todo this work?)
if err := obsMkdir(setting.CodePathPrefix + jobName + modelarts.OutputPath); err != nil {
log.Error("Failed to obsMkdir_output: %s (%v)", repo.FullName(), err)
- grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU)
- ctx.RenderWithErr("Failed to obsMkdir_output", tplGrampusTrainJobNPUNew, &form)
+ grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU)
+ ctx.RenderWithErr(ctx.Tr("cloudbrain.load_code_failed"), tplGrampusTrainJobNPUNew, &form)
return
}
if err := uploadCodeToObs(codeLocalPath, jobName, ""); err != nil {
log.Error("Failed to uploadCodeToObs: %s (%v)", repo.FullName(), err)
grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU)
- ctx.RenderWithErr("Failed to uploadCodeToObs", tplGrampusTrainJobNPUNew, &form)
+ ctx.RenderWithErr(ctx.Tr("cloudbrain.load_code_failed"), tplGrampusTrainJobNPUNew, &form)
return
}
diff --git a/routers/repo/modelarts.go b/routers/repo/modelarts.go
index 4be1389a2..8f43690ed 100755
--- a/routers/repo/modelarts.go
+++ b/routers/repo/modelarts.go
@@ -119,8 +119,7 @@ func MustEnableModelArts(ctx *context.Context) {
func NotebookNew(ctx *context.Context) {
notebookNewDataPrepare(ctx)
- waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "")
- ctx.Data["WaitCount"] = waitCount
+
ctx.HTML(200, tplModelArtsNotebookNew)
}
@@ -150,6 +149,9 @@ func notebookNewDataPrepare(ctx *context.Context) error {
ctx.Data["datasetType"] = models.TypeCloudBrainTwo
+ waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "")
+ ctx.Data["WaitCount"] = waitCount
+
return nil
}
@@ -676,8 +678,6 @@ func TrainJobNew(ctx *context.Context) {
ctx.ServerError("get new train-job info failed", err)
return
}
- waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "")
- ctx.Data["WaitCount"] = waitCount
ctx.HTML(200, tplModelArtsTrainJobNew)
}
@@ -747,6 +747,8 @@ func trainJobNewDataPrepare(ctx *context.Context) error {
}
ctx.Data["config_list"] = configList.ParaConfigs
ctx.Data["datasetType"] = models.TypeCloudBrainTwo
+ waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "")
+ ctx.Data["WaitCount"] = waitCount
return nil
}
@@ -863,6 +865,8 @@ func trainJobErrorNewDataPrepare(ctx *context.Context, form auth.CreateModelArts
ctx.Data["dataset_name"] = datasetNames
ctx.Data["branch_name"] = form.BranchName
ctx.Data["datasetType"] = models.TypeCloudBrainTwo
+ waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "")
+ ctx.Data["WaitCount"] = waitCount
return nil
}
@@ -874,8 +878,6 @@ func TrainJobNewVersion(ctx *context.Context) {
ctx.ServerError("get new train-job info failed", err)
return
}
- waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "")
- ctx.Data["WaitCount"] = waitCount
ctx.HTML(200, tplModelArtsTrainJobVersionNew)
}
@@ -968,6 +970,8 @@ func trainJobNewVersionDataPrepare(ctx *context.Context) error {
return err
}
ctx.Data["config_list"] = configList.ParaConfigs
+ waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "")
+ ctx.Data["WaitCount"] = waitCount
return nil
}
@@ -1059,6 +1063,8 @@ func versionErrorDataPrepare(ctx *context.Context, form auth.CreateModelArtsTrai
}
ctx.Data["config_list"] = configList.ParaConfigs
ctx.Data["datasetType"] = models.TypeCloudBrainTwo
+ waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "")
+ ctx.Data["WaitCount"] = waitCount
return nil
}
@@ -2324,8 +2330,7 @@ func InferenceJobNew(ctx *context.Context) {
ctx.ServerError("get new inference-job info failed", err)
return
}
- waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "")
- ctx.Data["WaitCount"] = waitCount
+
ctx.HTML(200, tplModelArtsInferenceJobNew)
}
func inferenceJobNewDataPrepare(ctx *context.Context) error {
@@ -2396,6 +2401,8 @@ func inferenceJobNewDataPrepare(ctx *context.Context) error {
})
ctx.Data["MODEL_COUNT"] = model_count
ctx.Data["datasetType"] = models.TypeCloudBrainTwo
+ waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "")
+ ctx.Data["WaitCount"] = waitCount
return nil
}
@@ -2469,6 +2476,8 @@ func inferenceJobErrorNewDataPrepare(ctx *context.Context, form auth.CreateModel
ctx.Data["ckpt_name"] = form.CkptName
ctx.Data["train_url"] = form.TrainUrl
ctx.Data["datasetType"] = models.TypeCloudBrainTwo
+ waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "")
+ ctx.Data["WaitCount"] = waitCount
return nil
}
diff --git a/templates/repo/cloudbrain/benchmark/index.tmpl b/templates/repo/cloudbrain/benchmark/index.tmpl
index c6283e2e1..8a2fbd51b 100755
--- a/templates/repo/cloudbrain/benchmark/index.tmpl
+++ b/templates/repo/cloudbrain/benchmark/index.tmpl
@@ -30,7 +30,7 @@
diff --git a/templates/repo/debugjob/index.tmpl b/templates/repo/debugjob/index.tmpl
index ee020a8ca..206b99a4e 100755
--- a/templates/repo/debugjob/index.tmpl
+++ b/templates/repo/debugjob/index.tmpl
@@ -230,7 +230,7 @@
{{$.i18n.Tr "repo.modelarts.notebook"}}
{{$.i18n.Tr "repo.modelarts.train_job"}}
+ href="{{.RepoLink}}/modelarts/train-job?listType=all">{{$.i18n.Tr "repo.modelarts.train_job"}}
{{$.i18n.Tr "repo.modelarts.infer_job"}}
diff --git a/templates/repo/modelarts/trainjob/index.tmpl b/templates/repo/modelarts/trainjob/index.tmpl
index 3e6645727..46c1b9a02 100755
--- a/templates/repo/modelarts/trainjob/index.tmpl
+++ b/templates/repo/modelarts/trainjob/index.tmpl
@@ -33,7 +33,7 @@
diff --git a/templates/repo/view_file.tmpl b/templates/repo/view_file.tmpl
index 91ec9b0bb..72446c3fe 100755
--- a/templates/repo/view_file.tmpl
+++ b/templates/repo/view_file.tmpl
@@ -133,16 +133,79 @@ function submitDeleteForm() {
$("#delete-file-form").submit()
}
}
+
+
+const baseUrls = {};
+const justDomain = /^[^:]+:\/*[^/]*$/;
+const protocol = /^([^:]+:)[\s\S]*$/;
+const domain = /^([^:]+:\/*[^/]*)[\s\S]*$/;
+const originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;
+function rtrim(str, c, invert) {
+ const l = str.length;
+ if (l === 0) {
+ return '';
+ }
+ let suffLen = 0;
+ while (suffLen < l) {
+ const currChar = str.charAt(l - suffLen - 1);
+ if (currChar === c && !invert) {
+ suffLen++;
+ } else if (currChar !== c && invert) {
+ suffLen++;
+ } else {
+ break;
+ }
+ }
+
+ return str.slice(0, l - suffLen);
+}
+function resolveUrl(base, href) {
+ if (!baseUrls[' ' + base]) {
+ if (justDomain.test(base)) {
+ baseUrls[' ' + base] = base + '/';
+ } else {
+ baseUrls[' ' + base] = rtrim(base, '/', true);
+ }
+ }
+ base = baseUrls[' ' + base];
+ const relativeBase = base.indexOf(':') === -1;
+
+ if (href.substring(0, 2) === '//') {
+ if (relativeBase) {
+ return href;
+ }
+ return base.replace(protocol, '$1') + href;
+ } else if (href.charAt(0) === '/') {
+ if (relativeBase) {
+ return href;
+ }
+ return base.replace(domain, '$1') + href;
+ } else {
+ return base + href;
+ }
+}
function showNoteBook(){
- var isNoteBook = {{.IsNoteBook}}
+ var isNoteBook = {{.IsNoteBook}};
if (isNoteBook) {
- var jsonStr = "{{.FileContent}}"
+ var jsonStr = "{{.FileContent}}";
+ var baseUrl={{.FileParentURL}};
nb.markdown.setOptions({
- baseUrl: {{.FileParentURL}}
+ baseUrl: baseUrl
});
var notebook = nb.parse(JSON.parse(jsonStr));
var rendered = notebook.render();
$("#notebook").append(rendered);
+
+ $("#notebook img").each(function(){
+
+ var oldSrc = $(this).attr('src');
+ if (!originIndependentUrl.test(oldSrc)){
+ var newSrc=resolveUrl(baseUrl,oldSrc);
+ $(this).attr('src', newSrc);
+
+ }
+
+ });
Prism.highlightAll();
}
}
diff --git a/vendor/github.com/yuin/goldmark/Makefile b/vendor/github.com/yuin/goldmark/Makefile
index 667a19a47..d0b99cff2 100644
--- a/vendor/github.com/yuin/goldmark/Makefile
+++ b/vendor/github.com/yuin/goldmark/Makefile
@@ -12,5 +12,5 @@ fuzz:
rm -rf ./fuzz/crashers
rm -rf ./fuzz/suppressions
rm -f ./fuzz/fuzz-fuzz.zip
- cd ./fuzz && go-fuzz-build
+ cd ./fuzz && GO111MODULE=off go-fuzz-build
cd ./fuzz && go-fuzz
diff --git a/vendor/github.com/yuin/goldmark/README.md b/vendor/github.com/yuin/goldmark/README.md
index b0923c930..e3d6918e6 100644
--- a/vendor/github.com/yuin/goldmark/README.md
+++ b/vendor/github.com/yuin/goldmark/README.md
@@ -1,14 +1,14 @@
goldmark
==========================================
-[](http://godoc.org/github.com/yuin/goldmark)
+[](https://pkg.go.dev/github.com/yuin/goldmark)
[](https://github.com/yuin/goldmark/actions?query=workflow:test)
[](https://coveralls.io/github/yuin/goldmark)
[](https://goreportcard.com/report/github.com/yuin/goldmark)
> A Markdown parser written in Go. Easy to extend, standards-compliant, well-structured.
-goldmark is compliant with CommonMark 0.29.
+goldmark is compliant with CommonMark 0.30.
Motivation
----------------------
@@ -173,6 +173,7 @@ Parser and Renderer options
- This extension enables Table, Strikethrough, Linkify and TaskList.
- This extension does not filter tags defined in [6.11: Disallowed Raw HTML (extension)](https://github.github.com/gfm/#disallowed-raw-html-extension-).
If you need to filter HTML tags, see [Security](#security).
+ - If you need to parse github emojis, you can use [goldmark-emoji](https://github.com/yuin/goldmark-emoji) extension.
- `extension.DefinitionList`
- [PHP Markdown Extra: Definition lists](https://michelf.ca/projects/php-markdown/extra/#def-list)
- `extension.Footnote`
@@ -203,6 +204,18 @@ heading {#id .className attrName=attrValue}
============
```
+### Table extension
+The Table extension implements [Table(extension)](https://github.github.com/gfm/#tables-extension-), as
+defined in [GitHub Flavored Markdown Spec](https://github.github.com/gfm/).
+
+Specs are defined for XHTML, so specs use some deprecated attributes for HTML5.
+
+You can override alignment rendering method via options.
+
+| Functional option | Type | Description |
+| ----------------- | ---- | ----------- |
+| `extension.WithTableCellAlignMethod` | `extension.TableCellAlignMethod` | Option indicates how are table cells aligned. |
+
### Typographer extension
The Typographer extension translates plain ASCII punctuation characters into typographic-punctuation HTML entities.
@@ -219,7 +232,7 @@ Default substitutions are:
| `<<` | `«` |
| `>>` | `»` |
-You can override the defualt substitutions via `extensions.WithTypographicSubstitutions`:
+You can override the default substitutions via `extensions.WithTypographicSubstitutions`:
```go
markdown := goldmark.New(
@@ -267,13 +280,96 @@ markdown := goldmark.New(
[]byte("https:"),
}),
extension.WithLinkifyURLRegexp(
- xurls.Strict(),
+ xurls.Strict,
),
),
),
)
```
+### Footnotes extension
+
+The Footnote extension implements [PHP Markdown Extra: Footnotes](https://michelf.ca/projects/php-markdown/extra/#footnotes).
+
+This extension has some options:
+
+| Functional option | Type | Description |
+| ----------------- | ---- | ----------- |
+| `extension.WithFootnoteIDPrefix` | `[]byte` | a prefix for the id attributes.|
+| `extension.WithFootnoteIDPrefixFunction` | `func(gast.Node) []byte` | a function that determines the id attribute for given Node.|
+| `extension.WithFootnoteLinkTitle` | `[]byte` | an optional title attribute for footnote links.|
+| `extension.WithFootnoteBacklinkTitle` | `[]byte` | an optional title attribute for footnote backlinks. |
+| `extension.WithFootnoteLinkClass` | `[]byte` | a class for footnote links. This defaults to `footnote-ref`. |
+| `extension.WithFootnoteBacklinkClass` | `[]byte` | a class for footnote backlinks. This defaults to `footnote-backref`. |
+| `extension.WithFootnoteBacklinkHTML` | `[]byte` | a class for footnote backlinks. This defaults to `↩︎`. |
+
+Some options can have special substitutions. Occurrences of “^^” in the string will be replaced by the corresponding footnote number in the HTML output. Occurrences of “%%” will be replaced by a number for the reference (footnotes can have multiple references).
+
+`extension.WithFootnoteIDPrefix` and `extension.WithFootnoteIDPrefixFunction` are useful if you have multiple Markdown documents displayed inside one HTML document to avoid footnote ids to clash each other.
+
+`extension.WithFootnoteIDPrefix` sets fixed id prefix, so you may write codes like the following:
+
+```go
+for _, path := range files {
+ source := readAll(path)
+ prefix := getPrefix(path)
+
+ markdown := goldmark.New(
+ goldmark.WithExtensions(
+ NewFootnote(
+ WithFootnoteIDPrefix([]byte(path)),
+ ),
+ ),
+ )
+ var b bytes.Buffer
+ err := markdown.Convert(source, &b)
+ if err != nil {
+ t.Error(err.Error())
+ }
+}
+```
+
+`extension.WithFootnoteIDPrefixFunction` determines an id prefix by calling given function, so you may write codes like the following:
+
+```go
+markdown := goldmark.New(
+ goldmark.WithExtensions(
+ NewFootnote(
+ WithFootnoteIDPrefixFunction(func(n gast.Node) []byte {
+ v, ok := n.OwnerDocument().Meta()["footnote-prefix"]
+ if ok {
+ return util.StringToReadOnlyBytes(v.(string))
+ }
+ return nil
+ }),
+ ),
+ ),
+)
+
+for _, path := range files {
+ source := readAll(path)
+ var b bytes.Buffer
+
+ doc := markdown.Parser().Parse(text.NewReader(source))
+ doc.Meta()["footnote-prefix"] = getPrefix(path)
+ err := markdown.Renderer().Render(&b, source, doc)
+}
+```
+
+You can use [goldmark-meta](https://github.com/yuin/goldmark-meta) to define a id prefix in the markdown document:
+
+
+```markdown
+---
+title: document title
+slug: article1
+footnote-prefix: article1
+---
+
+# My article
+
+```
+
Security
--------------------
By default, goldmark does not render raw HTML or potentially-dangerous URLs.
@@ -291,28 +387,29 @@ blackfriday v2 seems to be the fastest, but as it is not CommonMark compliant, i
goldmark, meanwhile, builds a clean, extensible AST structure, achieves full compliance with
CommonMark, and consumes less memory, all while being reasonably fast.
+- MBP 2019 13″(i5, 16GB), Go1.17
+
```
-goos: darwin
-goarch: amd64
-BenchmarkMarkdown/Blackfriday-v2-12 326 3465240 ns/op 3298861 B/op 20047 allocs/op
-BenchmarkMarkdown/GoldMark-12 303 3927494 ns/op 2574809 B/op 13853 allocs/op
-BenchmarkMarkdown/CommonMark-12 244 4900853 ns/op 2753851 B/op 20527 allocs/op
-BenchmarkMarkdown/Lute-12 130 9195245 ns/op 9175030 B/op 123534 allocs/op
-BenchmarkMarkdown/GoMarkdown-12 9 113541994 ns/op 2187472 B/op 22173 allocs/op
+BenchmarkMarkdown/Blackfriday-v2-8 302 3743747 ns/op 3290445 B/op 20050 allocs/op
+BenchmarkMarkdown/GoldMark-8 280 4200974 ns/op 2559738 B/op 13435 allocs/op
+BenchmarkMarkdown/CommonMark-8 226 5283686 ns/op 2702490 B/op 20792 allocs/op
+BenchmarkMarkdown/Lute-8 12 92652857 ns/op 10602649 B/op 40555 allocs/op
+BenchmarkMarkdown/GoMarkdown-8 13 81380167 ns/op 2245002 B/op 22889 allocs/op
```
### against cmark (CommonMark reference implementation written in C)
+- MBP 2019 13″(i5, 16GB), Go1.17
+
```
----------- cmark -----------
file: _data.md
iteration: 50
-average: 0.0037760639 sec
-go run ./goldmark_benchmark.go
+average: 0.0044073057 sec
------- goldmark -------
file: _data.md
iteration: 50
-average: 0.0040964230 sec
+average: 0.0041611990 sec
```
As you can see, goldmark's performance is on par with cmark's.
@@ -324,7 +421,17 @@ Extensions
extension for the goldmark Markdown parser.
- [goldmark-highlighting](https://github.com/yuin/goldmark-highlighting): A syntax-highlighting extension
for the goldmark markdown parser.
+- [goldmark-emoji](https://github.com/yuin/goldmark-emoji): An emoji
+ extension for the goldmark Markdown parser.
- [goldmark-mathjax](https://github.com/litao91/goldmark-mathjax): Mathjax support for the goldmark markdown parser
+- [goldmark-pdf](https://github.com/stephenafamo/goldmark-pdf): A PDF renderer that can be passed to `goldmark.WithRenderer()`.
+- [goldmark-hashtag](https://github.com/abhinav/goldmark-hashtag): Adds support for `#hashtag`-based tagging to goldmark.
+- [goldmark-wikilink](https://github.com/abhinav/goldmark-wikilink): Adds support for `[[wiki]]`-style links to goldmark.
+- [goldmark-toc](https://github.com/abhinav/goldmark-toc): Adds support for generating tables-of-contents for goldmark documents.
+- [goldmark-mermaid](https://github.com/abhinav/goldmark-mermaid): Adds support for rendering [Mermaid](https://mermaid-js.github.io/mermaid/) diagrams in goldmark documents.
+- [goldmark-pikchr](https://github.com/jchenry/goldmark-pikchr): Adds support for rendering [Pikchr](https://pikchr.org/home/doc/trunk/homepage.md) diagrams in goldmark documents.
+- [goldmark-embed](https://github.com/13rac1/goldmark-embed): Adds support for rendering embeds from YouTube links.
+
goldmark internal(for extension developers)
----------------------------------------------
diff --git a/vendor/github.com/yuin/goldmark/ast/ast.go b/vendor/github.com/yuin/goldmark/ast/ast.go
index 66059e94c..3719ebbd8 100644
--- a/vendor/github.com/yuin/goldmark/ast/ast.go
+++ b/vendor/github.com/yuin/goldmark/ast/ast.go
@@ -45,11 +45,6 @@ type Attribute struct {
Value interface{}
}
-var attrNameIDS = []byte("#")
-var attrNameID = []byte("id")
-var attrNameClassS = []byte(".")
-var attrNameClass = []byte("class")
-
// A Node interface defines basic AST node functionalities.
type Node interface {
// Type returns a type of this node.
@@ -116,6 +111,11 @@ type Node interface {
// tail of the children.
InsertAfter(self, v1, insertee Node)
+ // OwnerDocument returns this node's owner document.
+ // If this node is not a child of the Document node, OwnerDocument
+ // returns nil.
+ OwnerDocument() *Document
+
// Dump dumps an AST tree structure to stdout.
// This function completely aimed for debugging.
// level is a indent level. Implementer should indent informations with
@@ -169,7 +169,7 @@ type Node interface {
RemoveAttributes()
}
-// A BaseNode struct implements the Node interface.
+// A BaseNode struct implements the Node interface partialliy.
type BaseNode struct {
firstChild Node
lastChild Node
@@ -358,6 +358,22 @@ func (n *BaseNode) InsertBefore(self, v1, insertee Node) {
}
}
+// OwnerDocument implements Node.OwnerDocument
+func (n *BaseNode) OwnerDocument() *Document {
+ d := n.Parent()
+ for {
+ p := d.Parent()
+ if p == nil {
+ if v, ok := d.(*Document); ok {
+ return v
+ }
+ break
+ }
+ d = p
+ }
+ return nil
+}
+
// Text implements Node.Text .
func (n *BaseNode) Text(source []byte) []byte {
var buf bytes.Buffer
diff --git a/vendor/github.com/yuin/goldmark/ast/block.go b/vendor/github.com/yuin/goldmark/ast/block.go
index f5bca33fe..02e9d5190 100644
--- a/vendor/github.com/yuin/goldmark/ast/block.go
+++ b/vendor/github.com/yuin/goldmark/ast/block.go
@@ -7,7 +7,7 @@ import (
textm "github.com/yuin/goldmark/text"
)
-// A BaseBlock struct implements the Node interface.
+// A BaseBlock struct implements the Node interface partialliy.
type BaseBlock struct {
BaseNode
blankPreviousLines bool
@@ -50,6 +50,8 @@ func (b *BaseBlock) SetLines(v *textm.Segments) {
// A Document struct is a root node of Markdown text.
type Document struct {
BaseBlock
+
+ meta map[string]interface{}
}
// KindDocument is a NodeKind of the Document node.
@@ -70,10 +72,42 @@ func (n *Document) Kind() NodeKind {
return KindDocument
}
+// OwnerDocument implements Node.OwnerDocument
+func (n *Document) OwnerDocument() *Document {
+ return n
+}
+
+// Meta returns metadata of this document.
+func (n *Document) Meta() map[string]interface{} {
+ if n.meta == nil {
+ n.meta = map[string]interface{}{}
+ }
+ return n.meta
+}
+
+// SetMeta sets given metadata to this document.
+func (n *Document) SetMeta(meta map[string]interface{}) {
+ if n.meta == nil {
+ n.meta = map[string]interface{}{}
+ }
+ for k, v := range meta {
+ n.meta[k] = v
+ }
+}
+
+// AddMeta adds given metadata to this document.
+func (n *Document) AddMeta(key string, value interface{}) {
+ if n.meta == nil {
+ n.meta = map[string]interface{}{}
+ }
+ n.meta[key] = value
+}
+
// NewDocument returns a new Document node.
func NewDocument() *Document {
return &Document{
BaseBlock: BaseBlock{},
+ meta: nil,
}
}
@@ -311,7 +345,7 @@ type List struct {
Marker byte
// IsTight is a true if this list is a 'tight' list.
- // See https://spec.commonmark.org/0.29/#loose for details.
+ // See https://spec.commonmark.org/0.30/#loose for details.
IsTight bool
// Start is an initial number of this ordered list.
@@ -393,7 +427,7 @@ func NewListItem(offset int) *ListItem {
}
// HTMLBlockType represents kinds of an html blocks.
-// See https://spec.commonmark.org/0.29/#html-blocks
+// See https://spec.commonmark.org/0.30/#html-blocks
type HTMLBlockType int
const (
diff --git a/vendor/github.com/yuin/goldmark/ast/inline.go b/vendor/github.com/yuin/goldmark/ast/inline.go
index 23dcad4bc..fa6fc34f9 100644
--- a/vendor/github.com/yuin/goldmark/ast/inline.go
+++ b/vendor/github.com/yuin/goldmark/ast/inline.go
@@ -8,7 +8,7 @@ import (
"github.com/yuin/goldmark/util"
)
-// A BaseInline struct implements the Node interface.
+// A BaseInline struct implements the Node interface partialliy.
type BaseInline struct {
BaseNode
}
@@ -111,7 +111,7 @@ func (n *Text) SetRaw(v bool) {
}
// HardLineBreak returns true if this node ends with a hard line break.
-// See https://spec.commonmark.org/0.29/#hard-line-breaks for details.
+// See https://spec.commonmark.org/0.30/#hard-line-breaks for details.
func (n *Text) HardLineBreak() bool {
return n.flags&textHardLineBreak != 0
}
diff --git a/vendor/github.com/yuin/goldmark/extension/ast/footnote.go b/vendor/github.com/yuin/goldmark/extension/ast/footnote.go
index 835f8478b..97fea4403 100644
--- a/vendor/github.com/yuin/goldmark/extension/ast/footnote.go
+++ b/vendor/github.com/yuin/goldmark/extension/ast/footnote.go
@@ -2,6 +2,7 @@ package ast
import (
"fmt"
+
gast "github.com/yuin/goldmark/ast"
)
@@ -9,13 +10,17 @@ import (
// (PHP Markdown Extra) text.
type FootnoteLink struct {
gast.BaseInline
- Index int
+ Index int
+ RefCount int
+ RefIndex int
}
// Dump implements Node.Dump.
func (n *FootnoteLink) Dump(source []byte, level int) {
m := map[string]string{}
m["Index"] = fmt.Sprintf("%v", n.Index)
+ m["RefCount"] = fmt.Sprintf("%v", n.RefCount)
+ m["RefIndex"] = fmt.Sprintf("%v", n.RefIndex)
gast.DumpHelper(n, source, level, m, nil)
}
@@ -30,36 +35,44 @@ func (n *FootnoteLink) Kind() gast.NodeKind {
// NewFootnoteLink returns a new FootnoteLink node.
func NewFootnoteLink(index int) *FootnoteLink {
return &FootnoteLink{
- Index: index,
+ Index: index,
+ RefCount: 0,
+ RefIndex: 0,
}
}
-// A FootnoteBackLink struct represents a link to a footnote of Markdown
+// A FootnoteBacklink struct represents a link to a footnote of Markdown
// (PHP Markdown Extra) text.
-type FootnoteBackLink struct {
+type FootnoteBacklink struct {
gast.BaseInline
- Index int
+ Index int
+ RefCount int
+ RefIndex int
}
// Dump implements Node.Dump.
-func (n *FootnoteBackLink) Dump(source []byte, level int) {
+func (n *FootnoteBacklink) Dump(source []byte, level int) {
m := map[string]string{}
m["Index"] = fmt.Sprintf("%v", n.Index)
+ m["RefCount"] = fmt.Sprintf("%v", n.RefCount)
+ m["RefIndex"] = fmt.Sprintf("%v", n.RefIndex)
gast.DumpHelper(n, source, level, m, nil)
}
-// KindFootnoteBackLink is a NodeKind of the FootnoteBackLink node.
-var KindFootnoteBackLink = gast.NewNodeKind("FootnoteBackLink")
+// KindFootnoteBacklink is a NodeKind of the FootnoteBacklink node.
+var KindFootnoteBacklink = gast.NewNodeKind("FootnoteBacklink")
// Kind implements Node.Kind.
-func (n *FootnoteBackLink) Kind() gast.NodeKind {
- return KindFootnoteBackLink
+func (n *FootnoteBacklink) Kind() gast.NodeKind {
+ return KindFootnoteBacklink
}
-// NewFootnoteBackLink returns a new FootnoteBackLink node.
-func NewFootnoteBackLink(index int) *FootnoteBackLink {
- return &FootnoteBackLink{
- Index: index,
+// NewFootnoteBacklink returns a new FootnoteBacklink node.
+func NewFootnoteBacklink(index int) *FootnoteBacklink {
+ return &FootnoteBacklink{
+ Index: index,
+ RefCount: 0,
+ RefIndex: 0,
}
}
diff --git a/vendor/github.com/yuin/goldmark/extension/definition_list.go b/vendor/github.com/yuin/goldmark/extension/definition_list.go
index eb16dd03f..d2f5fecbe 100644
--- a/vendor/github.com/yuin/goldmark/extension/definition_list.go
+++ b/vendor/github.com/yuin/goldmark/extension/definition_list.go
@@ -138,7 +138,7 @@ func (b *definitionDescriptionParser) Open(parent gast.Node, reader text.Reader,
para.Parent().RemoveChild(para.Parent(), para)
}
cpos, padding := util.IndentPosition(line[pos+1:], pos+1, list.Offset-pos-1)
- reader.AdvanceAndSetPadding(cpos, padding)
+ reader.AdvanceAndSetPadding(cpos+1, padding)
return ast.NewDefinitionDescription(), parser.HasChildren
}
diff --git a/vendor/github.com/yuin/goldmark/extension/footnote.go b/vendor/github.com/yuin/goldmark/extension/footnote.go
index ede72db87..09b6fa8b0 100644
--- a/vendor/github.com/yuin/goldmark/extension/footnote.go
+++ b/vendor/github.com/yuin/goldmark/extension/footnote.go
@@ -2,6 +2,9 @@ package extension
import (
"bytes"
+ "fmt"
+ "strconv"
+
"github.com/yuin/goldmark"
gast "github.com/yuin/goldmark/ast"
"github.com/yuin/goldmark/extension/ast"
@@ -10,10 +13,10 @@ import (
"github.com/yuin/goldmark/renderer/html"
"github.com/yuin/goldmark/text"
"github.com/yuin/goldmark/util"
- "strconv"
)
var footnoteListKey = parser.NewContextKey()
+var footnoteLinkListKey = parser.NewContextKey()
type footnoteBlockParser struct {
}
@@ -164,7 +167,20 @@ func (s *footnoteParser) Parse(parent gast.Node, block text.Reader, pc parser.Co
return nil
}
- return ast.NewFootnoteLink(index)
+ fnlink := ast.NewFootnoteLink(index)
+ var fnlist []*ast.FootnoteLink
+ if tmp := pc.Get(footnoteLinkListKey); tmp != nil {
+ fnlist = tmp.([]*ast.FootnoteLink)
+ } else {
+ fnlist = []*ast.FootnoteLink{}
+ pc.Set(footnoteLinkListKey, fnlist)
+ }
+ pc.Set(footnoteLinkListKey, append(fnlist, fnlink))
+ if line[0] == '!' {
+ parent.AppendChild(parent, gast.NewTextSegment(text.NewSegment(segment.Start, segment.Start+1)))
+ }
+
+ return fnlink
}
type footnoteASTTransformer struct {
@@ -180,23 +196,62 @@ func NewFootnoteASTTransformer() parser.ASTTransformer {
func (a *footnoteASTTransformer) Transform(node *gast.Document, reader text.Reader, pc parser.Context) {
var list *ast.FootnoteList
- if tlist := pc.Get(footnoteListKey); tlist != nil {
- list = tlist.(*ast.FootnoteList)
- } else {
- return
+ var fnlist []*ast.FootnoteLink
+ if tmp := pc.Get(footnoteListKey); tmp != nil {
+ list = tmp.(*ast.FootnoteList)
+ }
+ if tmp := pc.Get(footnoteLinkListKey); tmp != nil {
+ fnlist = tmp.([]*ast.FootnoteLink)
}
+
pc.Set(footnoteListKey, nil)
+ pc.Set(footnoteLinkListKey, nil)
+
+ if list == nil {
+ return
+ }
+
+ counter := map[int]int{}
+ if fnlist != nil {
+ for _, fnlink := range fnlist {
+ if fnlink.Index >= 0 {
+ counter[fnlink.Index]++
+ }
+ }
+ refCounter := map[int]int{}
+ for _, fnlink := range fnlist {
+ fnlink.RefCount = counter[fnlink.Index]
+ if _, ok := refCounter[fnlink.Index]; !ok {
+ refCounter[fnlink.Index] = 0
+ }
+ fnlink.RefIndex = refCounter[fnlink.Index]
+ refCounter[fnlink.Index]++
+ }
+ }
for footnote := list.FirstChild(); footnote != nil; {
var container gast.Node = footnote
next := footnote.NextSibling()
if fc := container.LastChild(); fc != nil && gast.IsParagraph(fc) {
container = fc
}
- index := footnote.(*ast.Footnote).Index
+ fn := footnote.(*ast.Footnote)
+ index := fn.Index
if index < 0 {
list.RemoveChild(list, footnote)
} else {
- container.AppendChild(container, ast.NewFootnoteBackLink(index))
+ refCount := counter[index]
+ backLink := ast.NewFootnoteBacklink(index)
+ backLink.RefCount = refCount
+ backLink.RefIndex = 0
+ container.AppendChild(container, backLink)
+ if refCount > 1 {
+ for i := 1; i < refCount; i++ {
+ backLink := ast.NewFootnoteBacklink(index)
+ backLink.RefCount = refCount
+ backLink.RefIndex = i
+ container.AppendChild(container, backLink)
+ }
+ }
}
footnote = next
}
@@ -214,19 +269,250 @@ func (a *footnoteASTTransformer) Transform(node *gast.Document, reader text.Read
node.AppendChild(node, list)
}
+// FootnoteConfig holds configuration values for the footnote extension.
+//
+// Link* and Backlink* configurations have some variables:
+// Occurrances of “^^” in the string will be replaced by the
+// corresponding footnote number in the HTML output.
+// Occurrances of “%%” will be replaced by a number for the
+// reference (footnotes can have multiple references).
+type FootnoteConfig struct {
+ html.Config
+
+ // IDPrefix is a prefix for the id attributes generated by footnotes.
+ IDPrefix []byte
+
+ // IDPrefix is a function that determines the id attribute for given Node.
+ IDPrefixFunction func(gast.Node) []byte
+
+ // LinkTitle is an optional title attribute for footnote links.
+ LinkTitle []byte
+
+ // BacklinkTitle is an optional title attribute for footnote backlinks.
+ BacklinkTitle []byte
+
+ // LinkClass is a class for footnote links.
+ LinkClass []byte
+
+ // BacklinkClass is a class for footnote backlinks.
+ BacklinkClass []byte
+
+ // BacklinkHTML is an HTML content for footnote backlinks.
+ BacklinkHTML []byte
+}
+
+// FootnoteOption interface is a functional option interface for the extension.
+type FootnoteOption interface {
+ renderer.Option
+ // SetFootnoteOption sets given option to the extension.
+ SetFootnoteOption(*FootnoteConfig)
+}
+
+// NewFootnoteConfig returns a new Config with defaults.
+func NewFootnoteConfig() FootnoteConfig {
+ return FootnoteConfig{
+ Config: html.NewConfig(),
+ LinkTitle: []byte(""),
+ BacklinkTitle: []byte(""),
+ LinkClass: []byte("footnote-ref"),
+ BacklinkClass: []byte("footnote-backref"),
+ BacklinkHTML: []byte("↩︎"),
+ }
+}
+
+// SetOption implements renderer.SetOptioner.
+func (c *FootnoteConfig) SetOption(name renderer.OptionName, value interface{}) {
+ switch name {
+ case optFootnoteIDPrefixFunction:
+ c.IDPrefixFunction = value.(func(gast.Node) []byte)
+ case optFootnoteIDPrefix:
+ c.IDPrefix = value.([]byte)
+ case optFootnoteLinkTitle:
+ c.LinkTitle = value.([]byte)
+ case optFootnoteBacklinkTitle:
+ c.BacklinkTitle = value.([]byte)
+ case optFootnoteLinkClass:
+ c.LinkClass = value.([]byte)
+ case optFootnoteBacklinkClass:
+ c.BacklinkClass = value.([]byte)
+ case optFootnoteBacklinkHTML:
+ c.BacklinkHTML = value.([]byte)
+ default:
+ c.Config.SetOption(name, value)
+ }
+}
+
+type withFootnoteHTMLOptions struct {
+ value []html.Option
+}
+
+func (o *withFootnoteHTMLOptions) SetConfig(c *renderer.Config) {
+ if o.value != nil {
+ for _, v := range o.value {
+ v.(renderer.Option).SetConfig(c)
+ }
+ }
+}
+
+func (o *withFootnoteHTMLOptions) SetFootnoteOption(c *FootnoteConfig) {
+ if o.value != nil {
+ for _, v := range o.value {
+ v.SetHTMLOption(&c.Config)
+ }
+ }
+}
+
+// WithFootnoteHTMLOptions is functional option that wraps goldmark HTMLRenderer options.
+func WithFootnoteHTMLOptions(opts ...html.Option) FootnoteOption {
+ return &withFootnoteHTMLOptions{opts}
+}
+
+const optFootnoteIDPrefix renderer.OptionName = "FootnoteIDPrefix"
+
+type withFootnoteIDPrefix struct {
+ value []byte
+}
+
+func (o *withFootnoteIDPrefix) SetConfig(c *renderer.Config) {
+ c.Options[optFootnoteIDPrefix] = o.value
+}
+
+func (o *withFootnoteIDPrefix) SetFootnoteOption(c *FootnoteConfig) {
+ c.IDPrefix = o.value
+}
+
+// WithFootnoteIDPrefix is a functional option that is a prefix for the id attributes generated by footnotes.
+func WithFootnoteIDPrefix(a []byte) FootnoteOption {
+ return &withFootnoteIDPrefix{a}
+}
+
+const optFootnoteIDPrefixFunction renderer.OptionName = "FootnoteIDPrefixFunction"
+
+type withFootnoteIDPrefixFunction struct {
+ value func(gast.Node) []byte
+}
+
+func (o *withFootnoteIDPrefixFunction) SetConfig(c *renderer.Config) {
+ c.Options[optFootnoteIDPrefixFunction] = o.value
+}
+
+func (o *withFootnoteIDPrefixFunction) SetFootnoteOption(c *FootnoteConfig) {
+ c.IDPrefixFunction = o.value
+}
+
+// WithFootnoteIDPrefixFunction is a functional option that is a prefix for the id attributes generated by footnotes.
+func WithFootnoteIDPrefixFunction(a func(gast.Node) []byte) FootnoteOption {
+ return &withFootnoteIDPrefixFunction{a}
+}
+
+const optFootnoteLinkTitle renderer.OptionName = "FootnoteLinkTitle"
+
+type withFootnoteLinkTitle struct {
+ value []byte
+}
+
+func (o *withFootnoteLinkTitle) SetConfig(c *renderer.Config) {
+ c.Options[optFootnoteLinkTitle] = o.value
+}
+
+func (o *withFootnoteLinkTitle) SetFootnoteOption(c *FootnoteConfig) {
+ c.LinkTitle = o.value
+}
+
+// WithFootnoteLinkTitle is a functional option that is an optional title attribute for footnote links.
+func WithFootnoteLinkTitle(a []byte) FootnoteOption {
+ return &withFootnoteLinkTitle{a}
+}
+
+const optFootnoteBacklinkTitle renderer.OptionName = "FootnoteBacklinkTitle"
+
+type withFootnoteBacklinkTitle struct {
+ value []byte
+}
+
+func (o *withFootnoteBacklinkTitle) SetConfig(c *renderer.Config) {
+ c.Options[optFootnoteBacklinkTitle] = o.value
+}
+
+func (o *withFootnoteBacklinkTitle) SetFootnoteOption(c *FootnoteConfig) {
+ c.BacklinkTitle = o.value
+}
+
+// WithFootnoteBacklinkTitle is a functional option that is an optional title attribute for footnote backlinks.
+func WithFootnoteBacklinkTitle(a []byte) FootnoteOption {
+ return &withFootnoteBacklinkTitle{a}
+}
+
+const optFootnoteLinkClass renderer.OptionName = "FootnoteLinkClass"
+
+type withFootnoteLinkClass struct {
+ value []byte
+}
+
+func (o *withFootnoteLinkClass) SetConfig(c *renderer.Config) {
+ c.Options[optFootnoteLinkClass] = o.value
+}
+
+func (o *withFootnoteLinkClass) SetFootnoteOption(c *FootnoteConfig) {
+ c.LinkClass = o.value
+}
+
+// WithFootnoteLinkClass is a functional option that is a class for footnote links.
+func WithFootnoteLinkClass(a []byte) FootnoteOption {
+ return &withFootnoteLinkClass{a}
+}
+
+const optFootnoteBacklinkClass renderer.OptionName = "FootnoteBacklinkClass"
+
+type withFootnoteBacklinkClass struct {
+ value []byte
+}
+
+func (o *withFootnoteBacklinkClass) SetConfig(c *renderer.Config) {
+ c.Options[optFootnoteBacklinkClass] = o.value
+}
+
+func (o *withFootnoteBacklinkClass) SetFootnoteOption(c *FootnoteConfig) {
+ c.BacklinkClass = o.value
+}
+
+// WithFootnoteBacklinkClass is a functional option that is a class for footnote backlinks.
+func WithFootnoteBacklinkClass(a []byte) FootnoteOption {
+ return &withFootnoteBacklinkClass{a}
+}
+
+const optFootnoteBacklinkHTML renderer.OptionName = "FootnoteBacklinkHTML"
+
+type withFootnoteBacklinkHTML struct {
+ value []byte
+}
+
+func (o *withFootnoteBacklinkHTML) SetConfig(c *renderer.Config) {
+ c.Options[optFootnoteBacklinkHTML] = o.value
+}
+
+func (o *withFootnoteBacklinkHTML) SetFootnoteOption(c *FootnoteConfig) {
+ c.BacklinkHTML = o.value
+}
+
+// WithFootnoteBacklinkHTML is an HTML content for footnote backlinks.
+func WithFootnoteBacklinkHTML(a []byte) FootnoteOption {
+ return &withFootnoteBacklinkHTML{a}
+}
+
// FootnoteHTMLRenderer is a renderer.NodeRenderer implementation that
// renders FootnoteLink nodes.
type FootnoteHTMLRenderer struct {
- html.Config
+ FootnoteConfig
}
// NewFootnoteHTMLRenderer returns a new FootnoteHTMLRenderer.
-func NewFootnoteHTMLRenderer(opts ...html.Option) renderer.NodeRenderer {
+func NewFootnoteHTMLRenderer(opts ...FootnoteOption) renderer.NodeRenderer {
r := &FootnoteHTMLRenderer{
- Config: html.NewConfig(),
+ FootnoteConfig: NewFootnoteConfig(),
}
for _, opt := range opts {
- opt.SetHTMLOption(&r.Config)
+ opt.SetFootnoteOption(&r.FootnoteConfig)
}
return r
}
@@ -234,7 +520,7 @@ func NewFootnoteHTMLRenderer(opts ...html.Option) renderer.NodeRenderer {
// RegisterFuncs implements renderer.NodeRenderer.RegisterFuncs.
func (r *FootnoteHTMLRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) {
reg.Register(ast.KindFootnoteLink, r.renderFootnoteLink)
- reg.Register(ast.KindFootnoteBackLink, r.renderFootnoteBackLink)
+ reg.Register(ast.KindFootnoteBacklink, r.renderFootnoteBacklink)
reg.Register(ast.KindFootnote, r.renderFootnote)
reg.Register(ast.KindFootnoteList, r.renderFootnoteList)
}
@@ -243,25 +529,53 @@ func (r *FootnoteHTMLRenderer) renderFootnoteLink(w util.BufWriter, source []byt
if entering {
n := node.(*ast.FootnoteLink)
is := strconv.Itoa(n.Index)
- _, _ = w.WriteString(`
0 {
+ _, _ = w.WriteString(fmt.Sprintf("%v", n.RefIndex))
+ }
+ _ = w.WriteByte(':')
_, _ = w.WriteString(is)
- _, _ = w.WriteString(`">`)
}
return gast.WalkContinue, nil
}
-func (r *FootnoteHTMLRenderer) renderFootnoteBackLink(w util.BufWriter, source []byte, node gast.Node, entering bool) (gast.WalkStatus, error) {
+func (r *FootnoteHTMLRenderer) renderFootnoteBacklink(w util.BufWriter, source []byte, node gast.Node, entering bool) (gast.WalkStatus, error) {
if entering {
- n := node.(*ast.FootnoteBackLink)
+ n := node.(*ast.FootnoteBacklink)
is := strconv.Itoa(n.Index)
- _, _ = w.WriteString(`
0 {
+ _, _ = w.WriteString(fmt.Sprintf("%v", n.RefIndex))
+ }
+ _ = w.WriteByte(':')
_, _ = w.WriteString(is)
- _, _ = w.WriteString(`" class="footnote-backref" role="doc-backlink">`)
- _, _ = w.WriteString("↩︎")
+ _, _ = w.WriteString(`" class="`)
+ _, _ = w.Write(applyFootnoteTemplate(r.FootnoteConfig.BacklinkClass, n.Index, n.RefCount))
+ if len(r.FootnoteConfig.BacklinkTitle) > 0 {
+ _, _ = w.WriteString(`" title="`)
+ _, _ = w.Write(util.EscapeHTML(applyFootnoteTemplate(r.FootnoteConfig.BacklinkTitle, n.Index, n.RefCount)))
+ }
+ _, _ = w.WriteString(`" role="doc-backlink">`)
+ _, _ = w.Write(applyFootnoteTemplate(r.FootnoteConfig.BacklinkHTML, n.Index, n.RefCount))
_, _ = w.WriteString(``)
}
return gast.WalkContinue, nil
@@ -271,9 +585,11 @@ func (r *FootnoteHTMLRenderer) renderFootnote(w util.BufWriter, source []byte, n
n := node.(*ast.Footnote)
is := strconv.Itoa(n.Index)
if entering {
- _, _ = w.WriteString(`
\n")
}
return gast.WalkContinue, nil
}
+func (r *FootnoteHTMLRenderer) idPrefix(node gast.Node) []byte {
+ if r.FootnoteConfig.IDPrefix != nil {
+ return r.FootnoteConfig.IDPrefix
+ }
+ if r.FootnoteConfig.IDPrefixFunction != nil {
+ return r.FootnoteConfig.IDPrefixFunction(node)
+ }
+ return []byte("")
+}
+
+func applyFootnoteTemplate(b []byte, index, refCount int) []byte {
+ fast := true
+ for i, c := range b {
+ if i != 0 {
+ if b[i-1] == '^' && c == '^' {
+ fast = false
+ break
+ }
+ if b[i-1] == '%' && c == '%' {
+ fast = false
+ break
+ }
+ }
+ }
+ if fast {
+ return b
+ }
+ is := []byte(strconv.Itoa(index))
+ rs := []byte(strconv.Itoa(refCount))
+ ret := bytes.Replace(b, []byte("^^"), is, -1)
+ return bytes.Replace(ret, []byte("%%"), rs, -1)
+}
+
type footnote struct {
+ options []FootnoteOption
}
// Footnote is an extension that allow you to use PHP Markdown Extra Footnotes.
-var Footnote = &footnote{}
+var Footnote = &footnote{
+ options: []FootnoteOption{},
+}
+
+// NewFootnote returns a new extension with given options.
+func NewFootnote(opts ...FootnoteOption) goldmark.Extender {
+ return &footnote{
+ options: opts,
+ }
+}
func (e *footnote) Extend(m goldmark.Markdown) {
m.Parser().AddOptions(
@@ -331,6 +682,6 @@ func (e *footnote) Extend(m goldmark.Markdown) {
),
)
m.Renderer().AddOptions(renderer.WithNodeRenderers(
- util.Prioritized(NewFootnoteHTMLRenderer(), 500),
+ util.Prioritized(NewFootnoteHTMLRenderer(e.options...), 500),
))
}
diff --git a/vendor/github.com/yuin/goldmark/extension/linkify.go b/vendor/github.com/yuin/goldmark/extension/linkify.go
index 9e68fa534..2f046eb54 100644
--- a/vendor/github.com/yuin/goldmark/extension/linkify.go
+++ b/vendor/github.com/yuin/goldmark/extension/linkify.go
@@ -11,9 +11,9 @@ import (
"github.com/yuin/goldmark/util"
)
-var wwwURLRegxp = regexp.MustCompile(`^www\.[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]+(?:(?:/|[#?])[-a-zA-Z0-9@:%_\+.~#!?&//=\(\);,'">\^{}\[\]` + "`" + `]*)?`)
+var wwwURLRegxp = regexp.MustCompile(`^www\.[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-z]+(?:[/#?][-a-zA-Z0-9@:%_\+.~#!?&/=\(\);,'">\^{}\[\]` + "`" + `]*)?`)
-var urlRegexp = regexp.MustCompile(`^(?:http|https|ftp):\/\/(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]+(?:(?:/|[#?])[-a-zA-Z0-9@:%_+.~#$!?&//=\(\);,'">\^{}\[\]` + "`" + `]*)?`)
+var urlRegexp = regexp.MustCompile(`^(?:http|https|ftp)://[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-z]+(?::\d+)?(?:[/#?][-a-zA-Z0-9@:%_+.~#$!?&/=\(\);,'">\^{}\[\]` + "`" + `]*)?`)
// An LinkifyConfig struct is a data structure that holds configuration of the
// Linkify extension.
@@ -24,10 +24,12 @@ type LinkifyConfig struct {
EmailRegexp *regexp.Regexp
}
-const optLinkifyAllowedProtocols parser.OptionName = "LinkifyAllowedProtocols"
-const optLinkifyURLRegexp parser.OptionName = "LinkifyURLRegexp"
-const optLinkifyWWWRegexp parser.OptionName = "LinkifyWWWRegexp"
-const optLinkifyEmailRegexp parser.OptionName = "LinkifyEmailRegexp"
+const (
+ optLinkifyAllowedProtocols parser.OptionName = "LinkifyAllowedProtocols"
+ optLinkifyURLRegexp parser.OptionName = "LinkifyURLRegexp"
+ optLinkifyWWWRegexp parser.OptionName = "LinkifyWWWRegexp"
+ optLinkifyEmailRegexp parser.OptionName = "LinkifyEmailRegexp"
+)
// SetOption implements SetOptioner.
func (c *LinkifyConfig) SetOption(name parser.OptionName, value interface{}) {
@@ -156,10 +158,12 @@ func (s *linkifyParser) Trigger() []byte {
return []byte{' ', '*', '_', '~', '('}
}
-var protoHTTP = []byte("http:")
-var protoHTTPS = []byte("https:")
-var protoFTP = []byte("ftp:")
-var domainWWW = []byte("www.")
+var (
+ protoHTTP = []byte("http:")
+ protoHTTPS = []byte("https:")
+ protoFTP = []byte("ftp:")
+ domainWWW = []byte("www.")
+)
func (s *linkifyParser) Parse(parent ast.Node, block text.Reader, pc parser.Context) ast.Node {
if pc.IsInLinkLabel() {
@@ -269,9 +273,20 @@ func (s *linkifyParser) Parse(parent ast.Node, block text.Reader, pc parser.Cont
s := segment.WithStop(segment.Start + 1)
ast.MergeOrAppendTextSegment(parent, s)
}
- consumes += m[1]
+ i := m[1] - 1
+ for ; i > 0; i-- {
+ c := line[i]
+ switch c {
+ case '?', '!', '.', ',', ':', '*', '_', '~':
+ default:
+ goto endfor
+ }
+ }
+endfor:
+ i++
+ consumes += i
block.Advance(consumes)
- n := ast.NewTextSegment(text.NewSegment(start, start+m[1]))
+ n := ast.NewTextSegment(text.NewSegment(start, start+i))
link := ast.NewAutoLink(typ, n)
link.Protocol = protocol
return link
diff --git a/vendor/github.com/yuin/goldmark/extension/table.go b/vendor/github.com/yuin/goldmark/extension/table.go
index 91ba33199..c637b99f0 100644
--- a/vendor/github.com/yuin/goldmark/extension/table.go
+++ b/vendor/github.com/yuin/goldmark/extension/table.go
@@ -15,7 +15,121 @@ import (
"github.com/yuin/goldmark/util"
)
-var tableDelimRegexp = regexp.MustCompile(`^[\s\-\|\:]+$`)
+var escapedPipeCellListKey = parser.NewContextKey()
+
+type escapedPipeCell struct {
+ Cell *ast.TableCell
+ Pos []int
+ Transformed bool
+}
+
+// TableCellAlignMethod indicates how are table cells aligned in HTML format.indicates how are table cells aligned in HTML format.
+type TableCellAlignMethod int
+
+const (
+ // TableCellAlignDefault renders alignments by default method.
+ // With XHTML, alignments are rendered as an align attribute.
+ // With HTML5, alignments are rendered as a style attribute.
+ TableCellAlignDefault TableCellAlignMethod = iota
+
+ // TableCellAlignAttribute renders alignments as an align attribute.
+ TableCellAlignAttribute
+
+ // TableCellAlignStyle renders alignments as a style attribute.
+ TableCellAlignStyle
+
+ // TableCellAlignNone does not care about alignments.
+ // If you using classes or other styles, you can add these attributes
+ // in an ASTTransformer.
+ TableCellAlignNone
+)
+
+// TableConfig struct holds options for the extension.
+type TableConfig struct {
+ html.Config
+
+ // TableCellAlignMethod indicates how are table celss aligned.
+ TableCellAlignMethod TableCellAlignMethod
+}
+
+// TableOption interface is a functional option interface for the extension.
+type TableOption interface {
+ renderer.Option
+ // SetTableOption sets given option to the extension.
+ SetTableOption(*TableConfig)
+}
+
+// NewTableConfig returns a new Config with defaults.
+func NewTableConfig() TableConfig {
+ return TableConfig{
+ Config: html.NewConfig(),
+ TableCellAlignMethod: TableCellAlignDefault,
+ }
+}
+
+// SetOption implements renderer.SetOptioner.
+func (c *TableConfig) SetOption(name renderer.OptionName, value interface{}) {
+ switch name {
+ case optTableCellAlignMethod:
+ c.TableCellAlignMethod = value.(TableCellAlignMethod)
+ default:
+ c.Config.SetOption(name, value)
+ }
+}
+
+type withTableHTMLOptions struct {
+ value []html.Option
+}
+
+func (o *withTableHTMLOptions) SetConfig(c *renderer.Config) {
+ if o.value != nil {
+ for _, v := range o.value {
+ v.(renderer.Option).SetConfig(c)
+ }
+ }
+}
+
+func (o *withTableHTMLOptions) SetTableOption(c *TableConfig) {
+ if o.value != nil {
+ for _, v := range o.value {
+ v.SetHTMLOption(&c.Config)
+ }
+ }
+}
+
+// WithTableHTMLOptions is functional option that wraps goldmark HTMLRenderer options.
+func WithTableHTMLOptions(opts ...html.Option) TableOption {
+ return &withTableHTMLOptions{opts}
+}
+
+const optTableCellAlignMethod renderer.OptionName = "TableTableCellAlignMethod"
+
+type withTableCellAlignMethod struct {
+ value TableCellAlignMethod
+}
+
+func (o *withTableCellAlignMethod) SetConfig(c *renderer.Config) {
+ c.Options[optTableCellAlignMethod] = o.value
+}
+
+func (o *withTableCellAlignMethod) SetTableOption(c *TableConfig) {
+ c.TableCellAlignMethod = o.value
+}
+
+// WithTableCellAlignMethod is a functional option that indicates how are table cells aligned in HTML format.
+func WithTableCellAlignMethod(a TableCellAlignMethod) TableOption {
+ return &withTableCellAlignMethod{a}
+}
+
+func isTableDelim(bs []byte) bool {
+ for _, b := range bs {
+ if !(util.IsSpace(b) || b == '-' || b == '|' || b == ':') {
+ return false
+ }
+ }
+ return true
+}
+
var tableDelimLeft = regexp.MustCompile(`^\s*\:\-+\s*$`)
var tableDelimRight = regexp.MustCompile(`^\s*\-+\:\s*$`)
var tableDelimCenter = regexp.MustCompile(`^\s*\:\-+\:\s*$`)
@@ -37,25 +151,34 @@ func (b *tableParagraphTransformer) Transform(node *gast.Paragraph, reader text.
if lines.Len() < 2 {
return
}
- alignments := b.parseDelimiter(lines.At(1), reader)
- if alignments == nil {
- return
- }
- header := b.parseRow(lines.At(0), alignments, true, reader)
- if header == nil || len(alignments) != header.ChildCount() {
- return
- }
- table := ast.NewTable()
- table.Alignments = alignments
- table.AppendChild(table, ast.NewTableHeader(header))
- for i := 2; i < lines.Len(); i++ {
- table.AppendChild(table, b.parseRow(lines.At(i), alignments, false, reader))
+ for i := 1; i < lines.Len(); i++ {
+ alignments := b.parseDelimiter(lines.At(i), reader)
+ if alignments == nil {
+ continue
+ }
+ header := b.parseRow(lines.At(i-1), alignments, true, reader, pc)
+ if header == nil || len(alignments) != header.ChildCount() {
+ return
+ }
+ table := ast.NewTable()
+ table.Alignments = alignments
+ table.AppendChild(table, ast.NewTableHeader(header))
+ for j := i + 1; j < lines.Len(); j++ {
+ table.AppendChild(table, b.parseRow(lines.At(j), alignments, false, reader, pc))
+ }
+ node.Lines().SetSliced(0, i-1)
+ node.Parent().InsertAfter(node.Parent(), node, table)
+ if node.Lines().Len() == 0 {
+ node.Parent().RemoveChild(node.Parent(), node)
+ } else {
+ last := node.Lines().At(i - 2)
+ last.Stop = last.Stop - 1 // trim last newline(\n)
+ node.Lines().Set(i-2, last)
+ }
}
- node.Parent().InsertBefore(node.Parent(), node, table)
- node.Parent().RemoveChild(node.Parent(), node)
}
-func (b *tableParagraphTransformer) parseRow(segment text.Segment, alignments []ast.Alignment, isHeader bool, reader text.Reader) *ast.TableRow {
+func (b *tableParagraphTransformer) parseRow(segment text.Segment, alignments []ast.Alignment, isHeader bool, reader text.Reader, pc parser.Context) *ast.TableRow {
source := reader.Source()
line := segment.Value(source)
pos := 0
@@ -79,18 +202,39 @@ func (b *tableParagraphTransformer) parseRow(segment text.Segment, alignments []
} else {
alignment = alignments[i]
}
- closure := util.FindClosure(line[pos:], byte(0), '|', true, false)
- if closure < 0 {
- closure = len(line[pos:])
- }
+
+ var escapedCell *escapedPipeCell
node := ast.NewTableCell()
- seg := text.NewSegment(segment.Start+pos, segment.Start+pos+closure)
+ node.Alignment = alignment
+ hasBacktick := false
+ closure := pos
+ for ; closure < limit; closure++ {
+ if line[closure] == '`' {
+ hasBacktick = true
+ }
+ if line[closure] == '|' {
+ if closure == 0 || line[closure-1] != '\\' {
+ break
+ } else if hasBacktick {
+ if escapedCell == nil {
+ escapedCell = &escapedPipeCell{node, []int{}, false}
+ escapedList := pc.ComputeIfAbsent(escapedPipeCellListKey,
+ func() interface{} {
+ return []*escapedPipeCell{}
+ }).([]*escapedPipeCell)
+ escapedList = append(escapedList, escapedCell)
+ pc.Set(escapedPipeCellListKey, escapedList)
+ }
+ escapedCell.Pos = append(escapedCell.Pos, segment.Start+closure-1)
+ }
+ }
+ }
+ seg := text.NewSegment(segment.Start+pos, segment.Start+closure)
seg = seg.TrimLeftSpace(source)
seg = seg.TrimRightSpace(source)
node.Lines().Append(seg)
- node.Alignment = alignment
row.AppendChild(row, node)
- pos += closure + 1
+ pos = closure + 1
}
for ; i < len(alignments); i++ {
row.AppendChild(row, ast.NewTableCell())
@@ -100,7 +244,7 @@ func (b *tableParagraphTransformer) parseRow(segment text.Segment, alignments []
func (b *tableParagraphTransformer) parseDelimiter(segment text.Segment, reader text.Reader) []ast.Alignment {
line := segment.Value(reader.Source())
- if !tableDelimRegexp.Match(line) {
+ if !isTableDelim(line) {
return nil
}
cols := bytes.Split(line, []byte{'|'})
@@ -128,19 +272,74 @@ func (b *tableParagraphTransformer) parseDelimiter(segment text.Segment, reader
return alignments
}
+type tableASTTransformer struct {
+}
+
+var defaultTableASTTransformer = &tableASTTransformer{}
+
+// NewTableASTTransformer returns a parser.ASTTransformer for tables.
+func NewTableASTTransformer() parser.ASTTransformer {
+ return defaultTableASTTransformer
+}
+
+func (a *tableASTTransformer) Transform(node *gast.Document, reader text.Reader, pc parser.Context) {
+ lst := pc.Get(escapedPipeCellListKey)
+ if lst == nil {
+ return
+ }
+ pc.Set(escapedPipeCellListKey, nil)
+ for _, v := range lst.([]*escapedPipeCell) {
+ if v.Transformed {
+ continue
+ }
+ _ = gast.Walk(v.Cell, func(n gast.Node, entering bool) (gast.WalkStatus, error) {
+ if !entering || n.Kind() != gast.KindCodeSpan {
+ return gast.WalkContinue, nil
+ }
+
+ for c := n.FirstChild(); c != nil; {
+ next := c.NextSibling()
+ if c.Kind() != gast.KindText {
+ c = next
+ continue
+ }
+ parent := c.Parent()
+ ts := &c.(*gast.Text).Segment
+ n := c
+ for _, v := range lst.([]*escapedPipeCell) {
+ for _, pos := range v.Pos {
+ if ts.Start <= pos && pos < ts.Stop {
+ segment := n.(*gast.Text).Segment
+ n1 := gast.NewRawTextSegment(segment.WithStop(pos))
+ n2 := gast.NewRawTextSegment(segment.WithStart(pos + 1))
+ parent.InsertAfter(parent, n, n1)
+ parent.InsertAfter(parent, n1, n2)
+ parent.RemoveChild(parent, n)
+ n = n2
+ v.Transformed = true
+ }
+ }
+ }
+ c = next
+ }
+ return gast.WalkContinue, nil
+ })
+ }
+}
+
// TableHTMLRenderer is a renderer.NodeRenderer implementation that
// renders Table nodes.
type TableHTMLRenderer struct {
- html.Config
+ TableConfig
}
// NewTableHTMLRenderer returns a new TableHTMLRenderer.
-func NewTableHTMLRenderer(opts ...html.Option) renderer.NodeRenderer {
+func NewTableHTMLRenderer(opts ...TableOption) renderer.NodeRenderer {
r := &TableHTMLRenderer{
- Config: html.NewConfig(),
+ TableConfig: NewTableConfig(),
}
for _, opt := range opts {
- opt.SetHTMLOption(&r.Config)
+ opt.SetTableOption(&r.TableConfig)
}
return r
}
@@ -281,14 +480,33 @@ func (r *TableHTMLRenderer) renderTableCell(w util.BufWriter, source []byte, nod
tag = "th"
}
if entering {
- align := ""
+ fmt.Fprintf(w, "<%s", tag)
if n.Alignment != ast.AlignNone {
- if _, ok := n.AttributeString("align"); !ok { // Skip align render if overridden
- // TODO: "align" is deprecated. style="text-align:%s" instead?
- align = fmt.Sprintf(` align="%s"`, n.Alignment.String())
+ amethod := r.TableConfig.TableCellAlignMethod
+ if amethod == TableCellAlignDefault {
+ if r.Config.XHTML {
+ amethod = TableCellAlignAttribute
+ } else {
+ amethod = TableCellAlignStyle
+ }
+ }
+ switch amethod {
+ case TableCellAlignAttribute:
+ if _, ok := n.AttributeString("align"); !ok { // Skip align render if overridden
+ fmt.Fprintf(w, ` align="%s"`, n.Alignment.String())
+ }
+ case TableCellAlignStyle:
+ v, ok := n.AttributeString("style")
+ var cob util.CopyOnWriteBuffer
+ if ok {
+ cob = util.NewCopyOnWriteBuffer(v.([]byte))
+ cob.AppendByte(';')
+ }
+ style := fmt.Sprintf("text-align:%s", n.Alignment.String())
+ cob.AppendString(style)
+ n.SetAttributeString("style", cob.Bytes())
}
}
- fmt.Fprintf(w, "<%s", tag)
if n.Attributes() != nil {
if tag == "td" {
html.RenderAttributes(w, n, TableTdCellAttributeFilter) //
@@ -296,7 +514,7 @@ func (r *TableHTMLRenderer) renderTableCell(w util.BufWriter, source []byte, nod
html.RenderAttributes(w, n, TableThCellAttributeFilter) // |
}
}
- fmt.Fprintf(w, "%s>", align)
+ _ = w.WriteByte('>')
} else {
fmt.Fprintf(w, "%s>\n", tag)
}
@@ -304,16 +522,31 @@ func (r *TableHTMLRenderer) renderTableCell(w util.BufWriter, source []byte, nod
}
type table struct {
+ options []TableOption
}
// Table is an extension that allow you to use GFM tables .
-var Table = &table{}
+var Table = &table{
+ options: []TableOption{},
+}
+
+// NewTable returns a new extension with given options.
+func NewTable(opts ...TableOption) goldmark.Extender {
+ return &table{
+ options: opts,
+ }
+}
func (e *table) Extend(m goldmark.Markdown) {
- m.Parser().AddOptions(parser.WithParagraphTransformers(
- util.Prioritized(NewTableParagraphTransformer(), 200),
- ))
+ m.Parser().AddOptions(
+ parser.WithParagraphTransformers(
+ util.Prioritized(NewTableParagraphTransformer(), 200),
+ ),
+ parser.WithASTTransformers(
+ util.Prioritized(defaultTableASTTransformer, 0),
+ ),
+ )
m.Renderer().AddOptions(renderer.WithNodeRenderers(
- util.Prioritized(NewTableHTMLRenderer(), 500),
+ util.Prioritized(NewTableHTMLRenderer(e.options...), 500),
))
}
diff --git a/vendor/github.com/yuin/goldmark/extension/typographer.go b/vendor/github.com/yuin/goldmark/extension/typographer.go
index c3b975109..f56c06f74 100644
--- a/vendor/github.com/yuin/goldmark/extension/typographer.go
+++ b/vendor/github.com/yuin/goldmark/extension/typographer.go
@@ -10,6 +10,27 @@ import (
"github.com/yuin/goldmark/util"
)
+var uncloseCounterKey = parser.NewContextKey()
+
+type unclosedCounter struct {
+ Single int
+ Double int
+}
+
+func (u *unclosedCounter) Reset() {
+ u.Single = 0
+ u.Double = 0
+}
+
+func getUnclosedCounter(pc parser.Context) *unclosedCounter {
+ v := pc.Get(uncloseCounterKey)
+ if v == nil {
+ v = &unclosedCounter{}
+ pc.Set(uncloseCounterKey, v)
+ }
+ return v.(*unclosedCounter)
+}
+
// TypographicPunctuation is a key of the punctuations that can be replaced with
// typographic entities.
type TypographicPunctuation int
@@ -139,11 +160,10 @@ func NewTypographerParser(opts ...TypographerOption) parser.InlineParser {
}
func (s *typographerParser) Trigger() []byte {
- return []byte{'\'', '"', '-', '.', '<', '>'}
+ return []byte{'\'', '"', '-', '.', ',', '<', '>', '*', '['}
}
func (s *typographerParser) Parse(parent gast.Node, block text.Reader, pc parser.Context) gast.Node {
- before := block.PrecendingCharacter()
line, _ := block.PeekLine()
c := line[0]
if len(line) > 2 {
@@ -189,10 +209,12 @@ func (s *typographerParser) Parse(parent gast.Node, block text.Reader, pc parser
}
}
if c == '\'' || c == '"' {
+ before := block.PrecendingCharacter()
d := parser.ScanDelimiter(line, before, 1, defaultTypographerDelimiterProcessor)
if d == nil {
return nil
}
+ counter := getUnclosedCounter(pc)
if c == '\'' {
if s.Substitutions[Apostrophe] != nil {
// Handle decade abbrevations such as '90s
@@ -201,13 +223,20 @@ func (s *typographerParser) Parse(parent gast.Node, block text.Reader, pc parser
if len(line) > 4 {
after = util.ToRune(line, 4)
}
- if len(line) == 3 || unicode.IsSpace(after) || unicode.IsPunct(after) {
+ if len(line) == 3 || util.IsSpaceRune(after) || util.IsPunctRune(after) {
node := gast.NewString(s.Substitutions[Apostrophe])
node.SetCode(true)
block.Advance(1)
return node
}
}
+ // special cases: 'twas, 'em, 'net
+ if len(line) > 1 && (unicode.IsPunct(before) || unicode.IsSpace(before)) && (line[1] == 't' || line[1] == 'e' || line[1] == 'n' || line[1] == 'l') {
+ node := gast.NewString(s.Substitutions[Apostrophe])
+ node.SetCode(true)
+ block.Advance(1)
+ return node
+ }
// Convert normal apostrophes. This is probably more flexible than necessary but
// converts any apostrophe in between two alphanumerics.
if len(line) > 1 && (unicode.IsDigit(before) || unicode.IsLetter(before)) && (unicode.IsLetter(util.ToRune(line, 1))) {
@@ -218,16 +247,43 @@ func (s *typographerParser) Parse(parent gast.Node, block text.Reader, pc parser
}
}
if s.Substitutions[LeftSingleQuote] != nil && d.CanOpen && !d.CanClose {
- node := gast.NewString(s.Substitutions[LeftSingleQuote])
+ nt := LeftSingleQuote
+ // special cases: Alice's, I'm, Don't, You'd
+ if len(line) > 1 && (line[1] == 's' || line[1] == 'm' || line[1] == 't' || line[1] == 'd') && (len(line) < 3 || util.IsPunct(line[2]) || util.IsSpace(line[2])) {
+ nt = RightSingleQuote
+ }
+ // special cases: I've, I'll, You're
+ if len(line) > 2 && ((line[1] == 'v' && line[2] == 'e') || (line[1] == 'l' && line[2] == 'l') || (line[1] == 'r' && line[2] == 'e')) && (len(line) < 4 || util.IsPunct(line[3]) || util.IsSpace(line[3])) {
+ nt = RightSingleQuote
+ }
+ if nt == LeftSingleQuote {
+ counter.Single++
+ }
+
+ node := gast.NewString(s.Substitutions[nt])
node.SetCode(true)
block.Advance(1)
return node
}
- if s.Substitutions[RightSingleQuote] != nil && d.CanClose && !d.CanOpen {
- node := gast.NewString(s.Substitutions[RightSingleQuote])
- node.SetCode(true)
- block.Advance(1)
- return node
+ if s.Substitutions[RightSingleQuote] != nil {
+ // plural possesives and abbreviations: Smiths', doin'
+ if len(line) > 1 && unicode.IsSpace(util.ToRune(line, 0)) || unicode.IsPunct(util.ToRune(line, 0)) && (len(line) > 2 && !unicode.IsDigit(util.ToRune(line, 1))) {
+ node := gast.NewString(s.Substitutions[RightSingleQuote])
+ node.SetCode(true)
+ block.Advance(1)
+ return node
+ }
+ }
+ if s.Substitutions[RightSingleQuote] != nil && counter.Single > 0 {
+ isClose := d.CanClose && !d.CanOpen
+ maybeClose := d.CanClose && d.CanOpen && len(line) > 1 && unicode.IsPunct(util.ToRune(line, 1)) && (len(line) == 2 || (len(line) > 2 && util.IsPunct(line[2]) || util.IsSpace(line[2])))
+ if isClose || maybeClose {
+ node := gast.NewString(s.Substitutions[RightSingleQuote])
+ node.SetCode(true)
+ block.Advance(1)
+ counter.Single--
+ return node
+ }
}
}
if c == '"' {
@@ -235,13 +291,23 @@ func (s *typographerParser) Parse(parent gast.Node, block text.Reader, pc parser
node := gast.NewString(s.Substitutions[LeftDoubleQuote])
node.SetCode(true)
block.Advance(1)
+ counter.Double++
return node
}
- if s.Substitutions[RightDoubleQuote] != nil && d.CanClose && !d.CanOpen {
- node := gast.NewString(s.Substitutions[RightDoubleQuote])
- node.SetCode(true)
- block.Advance(1)
- return node
+ if s.Substitutions[RightDoubleQuote] != nil && counter.Double > 0 {
+ isClose := d.CanClose && !d.CanOpen
+ maybeClose := d.CanClose && d.CanOpen && len(line) > 1 && (unicode.IsPunct(util.ToRune(line, 1))) && (len(line) == 2 || (len(line) > 2 && util.IsPunct(line[2]) || util.IsSpace(line[2])))
+ if isClose || maybeClose {
+ // special case: "Monitor 21""
+ if len(line) > 1 && line[1] == '"' && unicode.IsDigit(before) {
+ return nil
+ }
+ node := gast.NewString(s.Substitutions[RightDoubleQuote])
+ node.SetCode(true)
+ block.Advance(1)
+ counter.Double--
+ return node
+ }
}
}
}
@@ -249,7 +315,7 @@ func (s *typographerParser) Parse(parent gast.Node, block text.Reader, pc parser
}
func (s *typographerParser) CloseBlock(parent gast.Node, pc parser.Context) {
- // nothing to do
+ getUnclosedCounter(pc).Reset()
}
type typographer struct {
diff --git a/vendor/github.com/yuin/goldmark/go.mod b/vendor/github.com/yuin/goldmark/go.mod
index a10efcad5..3a2e0db9e 100644
--- a/vendor/github.com/yuin/goldmark/go.mod
+++ b/vendor/github.com/yuin/goldmark/go.mod
@@ -1,3 +1,3 @@
module github.com/yuin/goldmark
-go 1.13
+go 1.18
diff --git a/vendor/github.com/yuin/goldmark/parser/attribute.go b/vendor/github.com/yuin/goldmark/parser/attribute.go
index ea8c0645d..f86c83610 100644
--- a/vendor/github.com/yuin/goldmark/parser/attribute.go
+++ b/vendor/github.com/yuin/goldmark/parser/attribute.go
@@ -89,7 +89,11 @@ func parseAttribute(reader text.Reader) (Attribute, bool) {
reader.Advance(1)
line, _ := reader.PeekLine()
i := 0
- for ; i < len(line) && !util.IsSpace(line[i]) && (!util.IsPunct(line[i]) || line[i] == '_' || line[i] == '-'); i++ {
+ // HTML5 allows any kind of characters as id, but XHTML restricts characters for id.
+ // CommonMark is basically defined for XHTML(even though it is legacy).
+ // So we restrict id characters.
+ for ; i < len(line) && !util.IsSpace(line[i]) &&
+ (!util.IsPunct(line[i]) || line[i] == '_' || line[i] == '-' || line[i] == ':' || line[i] == '.'); i++ {
}
name := attrNameClass
if c == '#' {
@@ -129,6 +133,11 @@ func parseAttribute(reader text.Reader) (Attribute, bool) {
if !ok {
return Attribute{}, false
}
+ if bytes.Equal(name, attrNameClass) {
+ if _, ok = value.([]byte); !ok {
+ return Attribute{}, false
+ }
+ }
return Attribute{Name: name, Value: value}, true
}
diff --git a/vendor/github.com/yuin/goldmark/parser/atx_heading.go b/vendor/github.com/yuin/goldmark/parser/atx_heading.go
index a631e0b1f..13a198b52 100644
--- a/vendor/github.com/yuin/goldmark/parser/atx_heading.go
+++ b/vendor/github.com/yuin/goldmark/parser/atx_heading.go
@@ -91,6 +91,9 @@ func (b *atxHeadingParser) Open(parent ast.Node, reader text.Reader, pc Context)
if i == pos || level > 6 {
return nil, NoChildren
}
+ if i == len(line) { // alone '#' (without a new line character)
+ return ast.NewHeading(level), NoChildren
+ }
l := util.TrimLeftSpaceLength(line[i:])
if l == 0 {
return nil, NoChildren
@@ -126,7 +129,8 @@ func (b *atxHeadingParser) Open(parent ast.Node, reader text.Reader, pc Context)
if closureClose > 0 {
reader.Advance(closureClose)
attrs, ok := ParseAttributes(reader)
- parsed = ok
+ rest, _ := reader.PeekLine()
+ parsed = ok && util.IsBlank(rest)
if parsed {
for _, attr := range attrs {
node.SetAttribute(attr.Name, attr.Value)
diff --git a/vendor/github.com/yuin/goldmark/parser/code_block.go b/vendor/github.com/yuin/goldmark/parser/code_block.go
index d02c21fc7..732f18c65 100644
--- a/vendor/github.com/yuin/goldmark/parser/code_block.go
+++ b/vendor/github.com/yuin/goldmark/parser/code_block.go
@@ -31,6 +31,10 @@ func (b *codeBlockParser) Open(parent ast.Node, reader text.Reader, pc Context)
node := ast.NewCodeBlock()
reader.AdvanceAndSetPadding(pos, padding)
_, segment = reader.PeekLine()
+ // if code block line starts with a tab, keep a tab as it is.
+ if segment.Padding != 0 {
+ preserveLeadingTabInCodeBlock(&segment, reader, 0)
+ }
node.Lines().Append(segment)
reader.Advance(segment.Len() - 1)
return node, NoChildren
@@ -49,6 +53,12 @@ func (b *codeBlockParser) Continue(node ast.Node, reader text.Reader, pc Context
}
reader.AdvanceAndSetPadding(pos, padding)
_, segment = reader.PeekLine()
+
+ // if code block line starts with a tab, keep a tab as it is.
+ if segment.Padding != 0 {
+ preserveLeadingTabInCodeBlock(&segment, reader, 0)
+ }
+
node.Lines().Append(segment)
reader.Advance(segment.Len() - 1)
return Continue | NoChildren
@@ -77,3 +87,14 @@ func (b *codeBlockParser) CanInterruptParagraph() bool {
func (b *codeBlockParser) CanAcceptIndentedLine() bool {
return true
}
+
+func preserveLeadingTabInCodeBlock(segment *text.Segment, reader text.Reader, indent int) {
+ offsetWithPadding := reader.LineOffset() + indent
+ sl, ss := reader.Position()
+ reader.SetPosition(sl, text.NewSegment(ss.Start-1, ss.Stop))
+ if offsetWithPadding == reader.LineOffset() {
+ segment.Padding = 0
+ segment.Start--
+ }
+ reader.SetPosition(sl, ss)
+}
diff --git a/vendor/github.com/yuin/goldmark/parser/code_span.go b/vendor/github.com/yuin/goldmark/parser/code_span.go
index 13652367f..a74b09bc4 100644
--- a/vendor/github.com/yuin/goldmark/parser/code_span.go
+++ b/vendor/github.com/yuin/goldmark/parser/code_span.go
@@ -3,7 +3,6 @@ package parser
import (
"github.com/yuin/goldmark/ast"
"github.com/yuin/goldmark/text"
- "github.com/yuin/goldmark/util"
)
type codeSpanParser struct {
@@ -52,9 +51,7 @@ func (s *codeSpanParser) Parse(parent ast.Node, block text.Reader, pc Context) a
}
}
}
- if !util.IsBlank(line) {
- node.AppendChild(node, ast.NewRawTextSegment(segment))
- }
+ node.AppendChild(node, ast.NewRawTextSegment(segment))
block.AdvanceLine()
}
end:
@@ -62,11 +59,11 @@ end:
// trim first halfspace and last halfspace
segment := node.FirstChild().(*ast.Text).Segment
shouldTrimmed := true
- if !(!segment.IsEmpty() && block.Source()[segment.Start] == ' ') {
+ if !(!segment.IsEmpty() && isSpaceOrNewline(block.Source()[segment.Start])) {
shouldTrimmed = false
}
segment = node.LastChild().(*ast.Text).Segment
- if !(!segment.IsEmpty() && block.Source()[segment.Stop-1] == ' ') {
+ if !(!segment.IsEmpty() && isSpaceOrNewline(block.Source()[segment.Stop-1])) {
shouldTrimmed = false
}
if shouldTrimmed {
@@ -81,3 +78,7 @@ end:
}
return node
}
+
+func isSpaceOrNewline(c byte) bool {
+ return c == ' ' || c == '\n'
+}
diff --git a/vendor/github.com/yuin/goldmark/parser/delimiter.go b/vendor/github.com/yuin/goldmark/parser/delimiter.go
index 612d7b737..eb843af44 100644
--- a/vendor/github.com/yuin/goldmark/parser/delimiter.go
+++ b/vendor/github.com/yuin/goldmark/parser/delimiter.go
@@ -3,7 +3,6 @@ package parser
import (
"fmt"
"strings"
- "unicode"
"github.com/yuin/goldmark/ast"
"github.com/yuin/goldmark/text"
@@ -31,11 +30,11 @@ type Delimiter struct {
Segment text.Segment
// CanOpen is set true if this delimiter can open a span for a new node.
- // See https://spec.commonmark.org/0.29/#can-open-emphasis for details.
+ // See https://spec.commonmark.org/0.30/#can-open-emphasis for details.
CanOpen bool
// CanClose is set true if this delimiter can close a span for a new node.
- // See https://spec.commonmark.org/0.29/#can-open-emphasis for details.
+ // See https://spec.commonmark.org/0.30/#can-open-emphasis for details.
CanClose bool
// Length is a remaining length of this delimiter.
@@ -128,10 +127,10 @@ func ScanDelimiter(line []byte, before rune, min int, processor DelimiterProcess
}
canOpen, canClose := false, false
- beforeIsPunctuation := unicode.IsPunct(before)
- beforeIsWhitespace := unicode.IsSpace(before)
- afterIsPunctuation := unicode.IsPunct(after)
- afterIsWhitespace := unicode.IsSpace(after)
+ beforeIsPunctuation := util.IsPunctRune(before)
+ beforeIsWhitespace := util.IsSpaceRune(before)
+ afterIsPunctuation := util.IsPunctRune(after)
+ afterIsWhitespace := util.IsSpaceRune(after)
isLeft := !afterIsWhitespace &&
(!afterIsPunctuation || beforeIsWhitespace || beforeIsPunctuation)
@@ -163,15 +162,11 @@ func ProcessDelimiters(bottom ast.Node, pc Context) {
var closer *Delimiter
if bottom != nil {
if bottom != lastDelimiter {
- for c := lastDelimiter.PreviousSibling(); c != nil; {
+ for c := lastDelimiter.PreviousSibling(); c != nil && c != bottom; {
if d, ok := c.(*Delimiter); ok {
closer = d
}
- prev := c.PreviousSibling()
- if prev == bottom {
- break
- }
- c = prev
+ c = c.PreviousSibling()
}
}
} else {
@@ -190,7 +185,7 @@ func ProcessDelimiters(bottom ast.Node, pc Context) {
found := false
maybeOpener := false
var opener *Delimiter
- for opener = closer.PreviousDelimiter; opener != nil; opener = opener.PreviousDelimiter {
+ for opener = closer.PreviousDelimiter; opener != nil && opener != bottom; opener = opener.PreviousDelimiter {
if opener.CanOpen && opener.Processor.CanOpenCloser(opener, closer) {
maybeOpener = true
consume = opener.CalcComsumption(closer)
@@ -201,10 +196,11 @@ func ProcessDelimiters(bottom ast.Node, pc Context) {
}
}
if !found {
+ next := closer.NextDelimiter
if !maybeOpener && !closer.CanOpen {
pc.RemoveDelimiter(closer)
}
- closer = closer.NextDelimiter
+ closer = next
continue
}
opener.ConsumeCharacters(consume)
diff --git a/vendor/github.com/yuin/goldmark/parser/fcode_block.go b/vendor/github.com/yuin/goldmark/parser/fcode_block.go
index f5b83eef7..5914138d3 100644
--- a/vendor/github.com/yuin/goldmark/parser/fcode_block.go
+++ b/vendor/github.com/yuin/goldmark/parser/fcode_block.go
@@ -71,6 +71,7 @@ func (b *fencedCodeBlockParser) Open(parent ast.Node, reader text.Reader, pc Con
func (b *fencedCodeBlockParser) Continue(node ast.Node, reader text.Reader, pc Context) State {
line, segment := reader.PeekLine()
fdata := pc.Get(fencedCodeBlockInfoKey).(*fenceData)
+
w, pos := util.IndentWidth(line, reader.LineOffset())
if w < 4 {
i := pos
@@ -86,9 +87,19 @@ func (b *fencedCodeBlockParser) Continue(node ast.Node, reader text.Reader, pc C
return Close
}
}
- pos, padding := util.DedentPositionPadding(line, reader.LineOffset(), segment.Padding, fdata.indent)
-
+ pos, padding := util.IndentPositionPadding(line, reader.LineOffset(), segment.Padding, fdata.indent)
+ if pos < 0 {
+ pos = util.FirstNonSpacePosition(line)
+ if pos < 0 {
+ pos = 0
+ }
+ padding = 0
+ }
seg := text.NewSegmentPadding(segment.Start+pos, segment.Stop, padding)
+ // if code block line starts with a tab, keep a tab as it is.
+ if padding != 0 {
+ preserveLeadingTabInCodeBlock(&seg, reader, fdata.indent)
+ }
node.Lines().Append(seg)
reader.AdvanceAndSetPadding(segment.Stop-segment.Start-pos-1, padding)
return Continue | NoChildren
diff --git a/vendor/github.com/yuin/goldmark/parser/html_block.go b/vendor/github.com/yuin/goldmark/parser/html_block.go
index 95b6918cd..380e723f2 100644
--- a/vendor/github.com/yuin/goldmark/parser/html_block.go
+++ b/vendor/github.com/yuin/goldmark/parser/html_block.go
@@ -76,8 +76,8 @@ var allowedBlockTags = map[string]bool{
"ul": true,
}
-var htmlBlockType1OpenRegexp = regexp.MustCompile(`(?i)^[ ]{0,3}<(script|pre|style)(?:\s.*|>.*|/>.*|)\n?$`)
-var htmlBlockType1CloseRegexp = regexp.MustCompile(`(?i)^.*(?:script|pre|style)>.*`)
+var htmlBlockType1OpenRegexp = regexp.MustCompile(`(?i)^[ ]{0,3}<(script|pre|style|textarea)(?:\s.*|>.*|/>.*|)(?:\r\n|\n)?$`)
+var htmlBlockType1CloseRegexp = regexp.MustCompile(`(?i)^.*(?:script|pre|style|textarea)>.*`)
var htmlBlockType2OpenRegexp = regexp.MustCompile(`^[ ]{0,3}'}
@@ -85,15 +85,15 @@ var htmlBlockType2Close = []byte{'-', '-', '>'}
var htmlBlockType3OpenRegexp = regexp.MustCompile(`^[ ]{0,3}<\?`)
var htmlBlockType3Close = []byte{'?', '>'}
-var htmlBlockType4OpenRegexp = regexp.MustCompile(`^[ ]{0,3}'}
var htmlBlockType5OpenRegexp = regexp.MustCompile(`^[ ]{0,3}<\!\[CDATA\[`)
var htmlBlockType5Close = []byte{']', ']', '>'}
-var htmlBlockType6Regexp = regexp.MustCompile(`^[ ]{0,3}?([a-zA-Z0-9]+)(?:\s.*|>.*|/>.*|)\n?$`)
+var htmlBlockType6Regexp = regexp.MustCompile(`^[ ]{0,3}<(?:/[ ]*)?([a-zA-Z]+[a-zA-Z0-9\-]*)(?:[ ].*|>.*|/>.*|)(?:\r\n|\n)?$`)
-var htmlBlockType7Regexp = regexp.MustCompile(`^[ ]{0,3}<(/)?([a-zA-Z0-9]+)(` + attributePattern + `*)(:?>|/>)\s*\n?$`)
+var htmlBlockType7Regexp = regexp.MustCompile(`^[ ]{0,3}<(/[ ]*)?([a-zA-Z]+[a-zA-Z0-9\-]*)(` + attributePattern + `*)[ ]*(?:>|/>)[ ]*(?:\r\n|\n)?$`)
type htmlBlockParser struct {
}
@@ -201,7 +201,7 @@ func (b *htmlBlockParser) Continue(node ast.Node, reader text.Reader, pc Context
}
if bytes.Contains(line, closurePattern) {
htmlBlock.ClosureLine = segment
- reader.Advance(segment.Len() - 1)
+ reader.Advance(segment.Len())
return Close
}
diff --git a/vendor/github.com/yuin/goldmark/parser/link.go b/vendor/github.com/yuin/goldmark/parser/link.go
index e7c6966f3..99583ac2a 100644
--- a/vendor/github.com/yuin/goldmark/parser/link.go
+++ b/vendor/github.com/yuin/goldmark/parser/link.go
@@ -2,7 +2,6 @@ package parser
import (
"fmt"
- "regexp"
"strings"
"github.com/yuin/goldmark/ast"
@@ -49,6 +48,13 @@ func (s *linkLabelState) Kind() ast.NodeKind {
return kindLinkLabelState
}
+func linkLabelStateLength(v *linkLabelState) int {
+ if v == nil || v.Last == nil || v.First == nil {
+ return 0
+ }
+ return v.Last.Segment.Stop - v.First.Segment.Start
+}
+
func pushLinkLabelState(pc Context, v *linkLabelState) {
tlist := pc.Get(linkLabelStateKey)
var list *linkLabelState
@@ -113,8 +119,6 @@ func (s *linkParser) Trigger() []byte {
return []byte{'!', '[', ']'}
}
-var linkDestinationRegexp = regexp.MustCompile(`\s*([^\s].+)`)
-var linkTitleRegexp = regexp.MustCompile(`\s+(\)|["'\(].+)`)
var linkBottom = NewContextKey()
func (s *linkParser) Parse(parent ast.Node, block text.Reader, pc Context) ast.Node {
@@ -143,7 +147,14 @@ func (s *linkParser) Parse(parent ast.Node, block text.Reader, pc Context) ast.N
}
block.Advance(1)
removeLinkLabelState(pc, last)
- if s.containsLink(last) { // a link in a link text is not allowed
+ // CommonMark spec says:
+ // > A link label can have at most 999 characters inside the square brackets.
+ if linkLabelStateLength(tlist.(*linkLabelState)) > 998 {
+ ast.MergeOrReplaceTextSegment(last.Parent(), last, last.Segment)
+ return nil
+ }
+
+ if !last.IsImage && s.containsLink(last) { // a link in a link text is not allowed
ast.MergeOrReplaceTextSegment(last.Parent(), last, last.Segment)
return nil
}
@@ -167,6 +178,13 @@ func (s *linkParser) Parse(parent ast.Node, block text.Reader, pc Context) ast.N
block.SetPosition(l, pos)
ssegment := text.NewSegment(last.Segment.Stop, segment.Start)
maybeReference := block.Value(ssegment)
+ // CommonMark spec says:
+ // > A link label can have at most 999 characters inside the square brackets.
+ if len(maybeReference) > 999 {
+ ast.MergeOrReplaceTextSegment(last.Parent(), last, last.Segment)
+ return nil
+ }
+
ref, ok := pc.Reference(util.ToLinkReference(maybeReference))
if !ok {
ast.MergeOrReplaceTextSegment(last.Parent(), last, last.Segment)
@@ -185,15 +203,17 @@ func (s *linkParser) Parse(parent ast.Node, block text.Reader, pc Context) ast.N
return link
}
-func (s *linkParser) containsLink(last *linkLabelState) bool {
- if last.IsImage {
+func (s *linkParser) containsLink(n ast.Node) bool {
+ if n == nil {
return false
}
- var c ast.Node
- for c = last; c != nil; c = c.NextSibling() {
+ for c := n; c != nil; c = c.NextSibling() {
if _, ok := c.(*ast.Link); ok {
return true
}
+ if s.containsLink(c.FirstChild()) {
+ return true
+ }
}
return false
}
@@ -224,21 +244,38 @@ func (s *linkParser) processLinkLabel(parent ast.Node, link *ast.Link, last *lin
}
}
+var linkFindClosureOptions text.FindClosureOptions = text.FindClosureOptions{
+ Nesting: false,
+ Newline: true,
+ Advance: true,
+}
+
func (s *linkParser) parseReferenceLink(parent ast.Node, last *linkLabelState, block text.Reader, pc Context) (*ast.Link, bool) {
_, orgpos := block.Position()
block.Advance(1) // skip '['
- line, segment := block.PeekLine()
- endIndex := util.FindClosure(line, '[', ']', false, true)
- if endIndex < 0 {
+ segments, found := block.FindClosure('[', ']', linkFindClosureOptions)
+ if !found {
return nil, false
}
- block.Advance(endIndex + 1)
- ssegment := segment.WithStop(segment.Start + endIndex)
- maybeReference := block.Value(ssegment)
+ var maybeReference []byte
+ if segments.Len() == 1 { // avoid allocate a new byte slice
+ maybeReference = block.Value(segments.At(0))
+ } else {
+ maybeReference = []byte{}
+ for i := 0; i < segments.Len(); i++ {
+ s := segments.At(i)
+ maybeReference = append(maybeReference, block.Value(s)...)
+ }
+ }
if util.IsBlank(maybeReference) { // collapsed reference link
- ssegment = text.NewSegment(last.Segment.Stop, orgpos.Start-1)
- maybeReference = block.Value(ssegment)
+ s := text.NewSegment(last.Segment.Stop, orgpos.Start-1)
+ maybeReference = block.Value(s)
+ }
+ // CommonMark spec says:
+ // > A link label can have at most 999 characters inside the square brackets.
+ if len(maybeReference) > 999 {
+ return nil, true
}
ref, ok := pc.Reference(util.ToLinkReference(maybeReference))
@@ -293,20 +330,17 @@ func (s *linkParser) parseLink(parent ast.Node, last *linkLabelState, block text
func parseLinkDestination(block text.Reader) ([]byte, bool) {
block.SkipSpaces()
line, _ := block.PeekLine()
- buf := []byte{}
if block.Peek() == '<' {
i := 1
for i < len(line) {
c := line[i]
if c == '\\' && i < len(line)-1 && util.IsPunct(line[i+1]) {
- buf = append(buf, '\\', line[i+1])
i += 2
continue
} else if c == '>' {
block.Advance(i + 1)
return line[1:i], true
}
- buf = append(buf, c)
i++
}
return nil, false
@@ -316,7 +350,6 @@ func parseLinkDestination(block text.Reader) ([]byte, bool) {
for i < len(line) {
c := line[i]
if c == '\\' && i < len(line)-1 && util.IsPunct(line[i+1]) {
- buf = append(buf, '\\', line[i+1])
i += 2
continue
} else if c == '(' {
@@ -329,7 +362,6 @@ func parseLinkDestination(block text.Reader) ([]byte, bool) {
} else if util.IsSpace(c) {
break
}
- buf = append(buf, c)
i++
}
block.Advance(i)
@@ -346,34 +378,24 @@ func parseLinkTitle(block text.Reader) ([]byte, bool) {
if opener == '(' {
closer = ')'
}
- savedLine, savedPosition := block.Position()
- var title []byte
- for i := 0; ; i++ {
- line, _ := block.PeekLine()
- if line == nil {
- block.SetPosition(savedLine, savedPosition)
- return nil, false
- }
- offset := 0
- if i == 0 {
- offset = 1
- }
- pos := util.FindClosure(line[offset:], opener, closer, false, true)
- if pos < 0 {
- title = append(title, line[offset:]...)
- block.AdvanceLine()
- continue
+ block.Advance(1)
+ segments, found := block.FindClosure(opener, closer, linkFindClosureOptions)
+ if found {
+ if segments.Len() == 1 {
+ return block.Value(segments.At(0)), true
}
- pos += offset + 1 // 1: closer
- block.Advance(pos)
- if i == 0 { // avoid allocating new slice
- return line[offset : pos-1], true
+ var title []byte
+ for i := 0; i < segments.Len(); i++ {
+ s := segments.At(i)
+ title = append(title, block.Value(s)...)
}
- return append(title, line[offset:pos-1]...), true
+ return title, true
}
+ return nil, false
}
func (s *linkParser) CloseBlock(parent ast.Node, block text.Reader, pc Context) {
+ pc.Set(linkBottom, nil)
tlist := pc.Get(linkLabelStateKey)
if tlist == nil {
return
diff --git a/vendor/github.com/yuin/goldmark/parser/link_ref.go b/vendor/github.com/yuin/goldmark/parser/link_ref.go
index 3fa1ecf6f..ea3f6544a 100644
--- a/vendor/github.com/yuin/goldmark/parser/link_ref.go
+++ b/vendor/github.com/yuin/goldmark/parser/link_ref.go
@@ -52,7 +52,7 @@ func (p *linkReferenceParagraphTransformer) Transform(node *ast.Paragraph, reade
func parseLinkReferenceDefinition(block text.Reader, pc Context) (int, int) {
block.SkipSpaces()
- line, segment := block.PeekLine()
+ line, _ := block.PeekLine()
if line == nil {
return -1, -1
}
@@ -67,39 +67,33 @@ func parseLinkReferenceDefinition(block text.Reader, pc Context) (int, int) {
if line[pos] != '[' {
return -1, -1
}
- open := segment.Start + pos + 1
- closes := -1
block.Advance(pos + 1)
- for {
- line, segment = block.PeekLine()
- if line == nil {
- return -1, -1
- }
- closure := util.FindClosure(line, '[', ']', false, false)
- if closure > -1 {
- closes = segment.Start + closure
- next := closure + 1
- if next >= len(line) || line[next] != ':' {
- return -1, -1
- }
- block.Advance(next + 1)
- break
+ segments, found := block.FindClosure('[', ']', linkFindClosureOptions)
+ if !found {
+ return -1, -1
+ }
+ var label []byte
+ if segments.Len() == 1 {
+ label = block.Value(segments.At(0))
+ } else {
+ for i := 0; i < segments.Len(); i++ {
+ s := segments.At(i)
+ label = append(label, block.Value(s)...)
}
- block.AdvanceLine()
}
- if closes < 0 {
+ if util.IsBlank(label) {
return -1, -1
}
- label := block.Value(text.NewSegment(open, closes))
- if util.IsBlank(label) {
+ if block.Peek() != ':' {
return -1, -1
}
+ block.Advance(1)
block.SkipSpaces()
destination, ok := parseLinkDestination(block)
if !ok {
return -1, -1
}
- line, segment = block.PeekLine()
+ line, _ = block.PeekLine()
isNewLine := line == nil || util.IsBlank(line)
endLine, _ := block.Position()
@@ -117,45 +111,40 @@ func parseLinkReferenceDefinition(block text.Reader, pc Context) (int, int) {
return -1, -1
}
block.Advance(1)
- open = -1
- closes = -1
closer := opener
if opener == '(' {
closer = ')'
}
- for {
- line, segment = block.PeekLine()
- if line == nil {
+ segments, found = block.FindClosure(opener, closer, linkFindClosureOptions)
+ if !found {
+ if !isNewLine {
return -1, -1
}
- if open < 0 {
- open = segment.Start
- }
- closure := util.FindClosure(line, opener, closer, false, true)
- if closure > -1 {
- closes = segment.Start + closure
- block.Advance(closure + 1)
- break
- }
+ ref := NewReference(label, destination, nil)
+ pc.AddReference(ref)
block.AdvanceLine()
+ return startLine, endLine + 1
}
- if closes < 0 {
- return -1, -1
+ var title []byte
+ if segments.Len() == 1 {
+ title = block.Value(segments.At(0))
+ } else {
+ for i := 0; i < segments.Len(); i++ {
+ s := segments.At(i)
+ title = append(title, block.Value(s)...)
+ }
}
- line, segment = block.PeekLine()
+ line, _ = block.PeekLine()
if line != nil && !util.IsBlank(line) {
if !isNewLine {
return -1, -1
}
- title := block.Value(text.NewSegment(open, closes))
ref := NewReference(label, destination, title)
pc.AddReference(ref)
return startLine, endLine
}
- title := block.Value(text.NewSegment(open, closes))
-
endLine, _ = block.Position()
ref := NewReference(label, destination, title)
pc.AddReference(ref)
diff --git a/vendor/github.com/yuin/goldmark/parser/list.go b/vendor/github.com/yuin/goldmark/parser/list.go
index 9183a6da3..e5cad1173 100644
--- a/vendor/github.com/yuin/goldmark/parser/list.go
+++ b/vendor/github.com/yuin/goldmark/parser/list.go
@@ -1,10 +1,11 @@
package parser
import (
+ "strconv"
+
"github.com/yuin/goldmark/ast"
"github.com/yuin/goldmark/text"
"github.com/yuin/goldmark/util"
- "strconv"
)
type listItemType int
@@ -15,6 +16,10 @@ const (
orderedList
)
+var skipListParserKey = NewContextKey()
+var emptyListItemWithBlankLines = NewContextKey()
+var listItemFlagValue interface{} = true
+
// Same as
// `^(([ ]*)([\-\*\+]))(\s+.*)?\n?$`.FindSubmatchIndex or
// `^(([ ]*)(\d{1,9}[\.\)]))(\s+.*)?\n?$`.FindSubmatchIndex
@@ -122,8 +127,8 @@ func (b *listParser) Trigger() []byte {
func (b *listParser) Open(parent ast.Node, reader text.Reader, pc Context) (ast.Node, State) {
last := pc.LastOpenedBlock().Node
- if _, lok := last.(*ast.List); lok || pc.Get(skipListParser) != nil {
- pc.Set(skipListParser, nil)
+ if _, lok := last.(*ast.List); lok || pc.Get(skipListParserKey) != nil {
+ pc.Set(skipListParserKey, nil)
return nil, NoChildren
}
line, _ := reader.PeekLine()
@@ -143,7 +148,7 @@ func (b *listParser) Open(parent ast.Node, reader text.Reader, pc Context) (ast.
return nil, NoChildren
}
//an empty list item cannot interrupt a paragraph:
- if match[5]-match[4] == 1 {
+ if match[4] < 0 || util.IsBlank(line[match[4]:match[5]]) {
return nil, NoChildren
}
}
@@ -153,6 +158,7 @@ func (b *listParser) Open(parent ast.Node, reader text.Reader, pc Context) (ast.
if start > -1 {
node.Start = start
}
+ pc.Set(emptyListItemWithBlankLines, nil)
return node, HasChildren
}
@@ -160,9 +166,8 @@ func (b *listParser) Continue(node ast.Node, reader text.Reader, pc Context) Sta
list := node.(*ast.List)
line, _ := reader.PeekLine()
if util.IsBlank(line) {
- // A list item can begin with at most one blank line
- if node.ChildCount() == 1 && node.LastChild().ChildCount() == 0 {
- return Close
+ if node.LastChild().ChildCount() == 0 {
+ pc.Set(emptyListItemWithBlankLines, listItemFlagValue)
}
return Continue | HasChildren
}
@@ -175,10 +180,23 @@ func (b *listParser) Continue(node ast.Node, reader text.Reader, pc Context) Sta
// - a
// - b <--- current line
// it maybe a new child of the list.
+ //
+ // Empty list items can have multiple blanklines
+ //
+ // - <--- 1st item is an empty thus "offset" is unknown
+ //
+ //
+ // - <--- current line
+ //
+ // -> 1 list with 2 blank items
+ //
+ // So if the last item is an empty, it maybe a new child of the list.
+ //
offset := lastOffset(node)
+ lastIsEmpty := node.LastChild().ChildCount() == 0
indent, _ := util.IndentWidth(line, reader.LineOffset())
- if indent < offset {
+ if indent < offset || lastIsEmpty {
if indent < 4 {
match, typ := matchesListItem(line, false) // may have a leading spaces more than 3
if typ != notList && match[1]-offset < 4 {
@@ -200,10 +218,27 @@ func (b *listParser) Continue(node ast.Node, reader text.Reader, pc Context) Sta
return Close
}
}
-
return Continue | HasChildren
}
}
+ if !lastIsEmpty {
+ return Close
+ }
+ }
+
+ if lastIsEmpty && indent < offset {
+ return Close
+ }
+
+ // Non empty items can not exist next to an empty list item
+ // with blank lines. So we need to close the current list
+ //
+ // -
+ //
+ // foo
+ //
+ // -> 1 list with 1 blank items and 1 paragraph
+ if pc.Get(emptyListItemWithBlankLines) != nil {
return Close
}
return Continue | HasChildren
@@ -230,8 +265,9 @@ func (b *listParser) Close(node ast.Node, reader text.Reader, pc Context) {
if list.IsTight {
for child := node.FirstChild(); child != nil; child = child.NextSibling() {
- for gc := child.FirstChild(); gc != nil; gc = gc.NextSibling() {
+ for gc := child.FirstChild(); gc != nil; {
paragraph, ok := gc.(*ast.Paragraph)
+ gc = gc.NextSibling()
if ok {
textBlock := ast.NewTextBlock()
textBlock.SetLines(paragraph.Lines())
diff --git a/vendor/github.com/yuin/goldmark/parser/list_item.go b/vendor/github.com/yuin/goldmark/parser/list_item.go
index 4a698d838..81357a9ad 100644
--- a/vendor/github.com/yuin/goldmark/parser/list_item.go
+++ b/vendor/github.com/yuin/goldmark/parser/list_item.go
@@ -17,9 +17,6 @@ func NewListItemParser() BlockParser {
return defaultListItemParser
}
-var skipListParser = NewContextKey()
-var skipListParserValue interface{} = true
-
func (b *listItemParser) Trigger() []byte {
return []byte{'-', '+', '*', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
}
@@ -38,9 +35,12 @@ func (b *listItemParser) Open(parent ast.Node, reader text.Reader, pc Context) (
if match[1]-offset > 3 {
return nil, NoChildren
}
+
+ pc.Set(emptyListItemWithBlankLines, nil)
+
itemOffset := calcListOffset(line, match)
node := ast.NewListItem(match[3] + itemOffset)
- if match[4] < 0 || match[5]-match[4] == 1 {
+ if match[4] < 0 || util.IsBlank(line[match[4]:match[5]]) {
return node, NoChildren
}
@@ -53,18 +53,23 @@ func (b *listItemParser) Open(parent ast.Node, reader text.Reader, pc Context) (
func (b *listItemParser) Continue(node ast.Node, reader text.Reader, pc Context) State {
line, _ := reader.PeekLine()
if util.IsBlank(line) {
+ reader.Advance(len(line) - 1)
return Continue | HasChildren
}
- indent, _ := util.IndentWidth(line, reader.LineOffset())
offset := lastOffset(node.Parent())
- if indent < offset && indent < 4 {
+ isEmpty := node.ChildCount() == 0
+ indent, _ := util.IndentWidth(line, reader.LineOffset())
+ if (isEmpty || indent < offset) && indent < 4 {
_, typ := matchesListItem(line, true)
// new list item found
if typ != notList {
- pc.Set(skipListParser, skipListParserValue)
+ pc.Set(skipListParserKey, listItemFlagValue)
+ return Close
+ }
+ if !isEmpty {
+ return Close
}
- return Close
}
pos, padding := util.IndentPosition(line, reader.LineOffset(), offset)
reader.AdvanceAndSetPadding(pos, padding)
diff --git a/vendor/github.com/yuin/goldmark/parser/parser.go b/vendor/github.com/yuin/goldmark/parser/parser.go
index def13db66..bac070452 100644
--- a/vendor/github.com/yuin/goldmark/parser/parser.go
+++ b/vendor/github.com/yuin/goldmark/parser/parser.go
@@ -138,6 +138,9 @@ type Context interface {
// Get returns a value associated with the given key.
Get(ContextKey) interface{}
+ // ComputeIfAbsent computes a value if a value associated with the given key is absent and returns the value.
+ ComputeIfAbsent(ContextKey, func() interface{}) interface{}
+
// Set sets the given value to the context.
Set(ContextKey, interface{})
@@ -252,6 +255,15 @@ func (p *parseContext) Get(key ContextKey) interface{} {
return p.store[key]
}
+func (p *parseContext) ComputeIfAbsent(key ContextKey, f func() interface{}) interface{} {
+ v := p.store[key]
+ if v == nil {
+ v = f()
+ p.store[key] = v
+ }
+ return v
+}
+
func (p *parseContext) Set(key ContextKey, value interface{}) {
p.store[key] = value
}
@@ -1103,6 +1115,12 @@ func (p *parser) walkBlock(block ast.Node, cb func(node ast.Node)) {
cb(block)
}
+const (
+ lineBreakHard uint8 = 1 << iota
+ lineBreakSoft
+ lineBreakVisible
+)
+
func (p *parser) parseBlock(block text.BlockReader, parent ast.Node, pc Context) {
if parent.IsRaw() {
return
@@ -1117,21 +1135,25 @@ func (p *parser) parseBlock(block text.BlockReader, parent ast.Node, pc Context)
break
}
lineLength := len(line)
- hardlineBreak := false
- softLinebreak := line[lineLength-1] == '\n'
- if lineLength >= 2 && line[lineLength-2] == '\\' && softLinebreak { // ends with \\n
+ var lineBreakFlags uint8 = 0
+ hasNewLine := line[lineLength-1] == '\n'
+ if ((lineLength >= 3 && line[lineLength-2] == '\\' && line[lineLength-3] != '\\') || (lineLength == 2 && line[lineLength-2] == '\\')) && hasNewLine { // ends with \\n
lineLength -= 2
- hardlineBreak = true
-
- } else if lineLength >= 3 && line[lineLength-3] == '\\' && line[lineLength-2] == '\r' && softLinebreak { // ends with \\r\n
+ lineBreakFlags |= lineBreakHard | lineBreakVisible
+ } else if ((lineLength >= 4 && line[lineLength-3] == '\\' && line[lineLength-2] == '\r' && line[lineLength-4] != '\\') || (lineLength == 3 && line[lineLength-3] == '\\' && line[lineLength-2] == '\r')) && hasNewLine { // ends with \\r\n
lineLength -= 3
- hardlineBreak = true
- } else if lineLength >= 3 && line[lineLength-3] == ' ' && line[lineLength-2] == ' ' && softLinebreak { // ends with [space][space]\n
+ lineBreakFlags |= lineBreakHard | lineBreakVisible
+ } else if lineLength >= 3 && line[lineLength-3] == ' ' && line[lineLength-2] == ' ' && hasNewLine { // ends with [space][space]\n
lineLength -= 3
- hardlineBreak = true
- } else if lineLength >= 4 && line[lineLength-4] == ' ' && line[lineLength-3] == ' ' && line[lineLength-2] == '\r' && softLinebreak { // ends with [space][space]\r\n
+ lineBreakFlags |= lineBreakHard
+ } else if lineLength >= 4 && line[lineLength-4] == ' ' && line[lineLength-3] == ' ' && line[lineLength-2] == '\r' && hasNewLine { // ends with [space][space]\r\n
lineLength -= 4
- hardlineBreak = true
+ lineBreakFlags |= lineBreakHard
+ } else if hasNewLine {
+ // If the line ends with a newline character, but it is not a hardlineBreak, then it is a softLinebreak
+ // If the line ends with a hardlineBreak, then it cannot end with a softLinebreak
+ // See https://spec.commonmark.org/0.30/#soft-line-breaks
+ lineBreakFlags |= lineBreakSoft
}
l, startPosition := block.Position()
@@ -1195,11 +1217,14 @@ func (p *parser) parseBlock(block text.BlockReader, parent ast.Node, pc Context)
continue
}
diff := startPosition.Between(currentPosition)
- stop := diff.Stop
- rest := diff.WithStop(stop)
- text := ast.NewTextSegment(rest.TrimRightSpace(source))
- text.SetSoftLineBreak(softLinebreak)
- text.SetHardLineBreak(hardlineBreak)
+ var text *ast.Text
+ if lineBreakFlags&(lineBreakHard|lineBreakVisible) == lineBreakHard|lineBreakVisible {
+ text = ast.NewTextSegment(diff)
+ } else {
+ text = ast.NewTextSegment(diff.TrimRightSpace(source))
+ }
+ text.SetSoftLineBreak(lineBreakFlags&lineBreakSoft != 0)
+ text.SetHardLineBreak(lineBreakFlags&lineBreakHard != 0)
parent.AppendChild(parent, text)
block.AdvanceLine()
}
diff --git a/vendor/github.com/yuin/goldmark/parser/raw_html.go b/vendor/github.com/yuin/goldmark/parser/raw_html.go
index d7ba414ff..55b9a9967 100644
--- a/vendor/github.com/yuin/goldmark/parser/raw_html.go
+++ b/vendor/github.com/yuin/goldmark/parser/raw_html.go
@@ -2,10 +2,11 @@ package parser
import (
"bytes"
+ "regexp"
+
"github.com/yuin/goldmark/ast"
"github.com/yuin/goldmark/text"
"github.com/yuin/goldmark/util"
- "regexp"
)
type rawHTMLParser struct {
@@ -31,43 +32,101 @@ func (s *rawHTMLParser) Parse(parent ast.Node, block text.Reader, pc Context) as
if len(line) > 2 && line[1] == '/' && util.IsAlphaNumeric(line[2]) {
return s.parseMultiLineRegexp(closeTagRegexp, block, pc)
}
- if bytes.HasPrefix(line, []byte("|`)
-var processingInstructionRegexp = regexp.MustCompile(`^(?:<\?).*?(?:\?>)`)
-var declRegexp = regexp.MustCompile(`^]*>`)
-var cdataRegexp = regexp.MustCompile(``)
-func (s *rawHTMLParser) parseSingleLineRegexp(reg *regexp.Regexp, block text.Reader, pc Context) ast.Node {
+var openProcessingInstruction = []byte("")
+var closeProcessingInstruction = []byte("?>")
+var openCDATA = []byte("")
+var closeDecl = []byte(">")
+var emptyComment = []byte("")
+var invalidComment1 = []byte("")
+var invalidComment2 = []byte("")
+var openComment = []byte("")
+var doubleHyphen = []byte("--")
+
+func (s *rawHTMLParser) parseComment(block text.Reader, pc Context) ast.Node {
+ savedLine, savedSegment := block.Position()
+ node := ast.NewRawHTML()
line, segment := block.PeekLine()
- match := reg.FindSubmatchIndex(line)
- if match == nil {
+ if bytes.HasPrefix(line, emptyComment) {
+ node.Segments.Append(segment.WithStop(segment.Start + len(emptyComment)))
+ block.Advance(len(emptyComment))
+ return node
+ }
+ if bytes.HasPrefix(line, invalidComment1) || bytes.HasPrefix(line, invalidComment2) {
return nil
}
- node := ast.NewRawHTML()
- node.Segments.Append(segment.WithStop(segment.Start + match[1]))
- block.Advance(match[1])
- return node
+ offset := len(openComment)
+ line = line[offset:]
+ for {
+ hindex := bytes.Index(line, doubleHyphen)
+ if hindex > -1 {
+ hindex += offset
+ }
+ index := bytes.Index(line, closeComment) + offset
+ if index > -1 && hindex == index {
+ if index == 0 || len(line) < 2 || line[index-offset-1] != '-' {
+ node.Segments.Append(segment.WithStop(segment.Start + index + len(closeComment)))
+ block.Advance(index + len(closeComment))
+ return node
+ }
+ }
+ if hindex > 0 {
+ break
+ }
+ node.Segments.Append(segment)
+ block.AdvanceLine()
+ line, segment = block.PeekLine()
+ offset = 0
+ if line == nil {
+ break
+ }
+ }
+ block.SetPosition(savedLine, savedSegment)
+ return nil
}
-var dummyMatch = [][]byte{}
+func (s *rawHTMLParser) parseUntil(block text.Reader, closer []byte, pc Context) ast.Node {
+ savedLine, savedSegment := block.Position()
+ node := ast.NewRawHTML()
+ for {
+ line, segment := block.PeekLine()
+ if line == nil {
+ break
+ }
+ index := bytes.Index(line, closer)
+ if index > -1 {
+ node.Segments.Append(segment.WithStop(segment.Start + index + len(closer)))
+ block.Advance(index + len(closer))
+ return node
+ }
+ node.Segments.Append(segment)
+ block.AdvanceLine()
+ }
+ block.SetPosition(savedLine, savedSegment)
+ return nil
+}
func (s *rawHTMLParser) parseMultiLineRegexp(reg *regexp.Regexp, block text.Reader, pc Context) ast.Node {
sline, ssegment := block.Position()
@@ -102,7 +161,3 @@ func (s *rawHTMLParser) parseMultiLineRegexp(reg *regexp.Regexp, block text.Read
}
return nil
}
-
-func (s *rawHTMLParser) CloseBlock(parent ast.Node, pc Context) {
- // nothing to do
-}
diff --git a/vendor/github.com/yuin/goldmark/renderer/html/html.go b/vendor/github.com/yuin/goldmark/renderer/html/html.go
index 537a256fe..12fa7ce2c 100644
--- a/vendor/github.com/yuin/goldmark/renderer/html/html.go
+++ b/vendor/github.com/yuin/goldmark/renderer/html/html.go
@@ -198,16 +198,24 @@ func (r *Renderer) writeLines(w util.BufWriter, source []byte, n ast.Node) {
var GlobalAttributeFilter = util.NewBytesFilter(
[]byte("accesskey"),
[]byte("autocapitalize"),
+ []byte("autofocus"),
[]byte("class"),
[]byte("contenteditable"),
- []byte("contextmenu"),
[]byte("dir"),
[]byte("draggable"),
- []byte("dropzone"),
+ []byte("enterkeyhint"),
[]byte("hidden"),
[]byte("id"),
+ []byte("inert"),
+ []byte("inputmode"),
+ []byte("is"),
+ []byte("itemid"),
[]byte("itemprop"),
+ []byte("itemref"),
+ []byte("itemscope"),
+ []byte("itemtype"),
[]byte("lang"),
+ []byte("part"),
[]byte("slot"),
[]byte("spellcheck"),
[]byte("style"),
@@ -296,7 +304,7 @@ func (r *Renderer) renderHTMLBlock(w util.BufWriter, source []byte, node ast.Nod
l := n.Lines().Len()
for i := 0; i < l; i++ {
line := n.Lines().At(i)
- _, _ = w.Write(line.Value(source))
+ r.Writer.SecureWrite(w, line.Value(source))
}
} else {
_, _ = w.WriteString("\n")
@@ -305,7 +313,7 @@ func (r *Renderer) renderHTMLBlock(w util.BufWriter, source []byte, node ast.Nod
if n.HasClosure() {
if r.Unsafe {
closure := n.ClosureLine
- _, _ = w.Write(closure.Value(source))
+ r.Writer.SecureWrite(w, closure.Value(source))
} else {
_, _ = w.WriteString("\n")
}
@@ -318,6 +326,7 @@ func (r *Renderer) renderHTMLBlock(w util.BufWriter, source []byte, node ast.Nod
var ListAttributeFilter = GlobalAttributeFilter.Extend(
[]byte("start"),
[]byte("reversed"),
+ []byte("type"),
)
func (r *Renderer) renderList(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
@@ -476,9 +485,7 @@ func (r *Renderer) renderCodeSpan(w util.BufWriter, source []byte, n ast.Node, e
value := segment.Value(source)
if bytes.HasSuffix(value, []byte("\n")) {
r.Writer.RawWrite(w, value[:len(value)-1])
- if c != n.LastChild() {
- r.Writer.RawWrite(w, []byte(" "))
- }
+ r.Writer.RawWrite(w, []byte(" "))
} else {
r.Writer.RawWrite(w, value)
}
@@ -564,7 +571,7 @@ func (r *Renderer) renderImage(w util.BufWriter, source []byte, node ast.Node, e
_, _ = w.Write(util.EscapeHTML(util.URLEscape(n.Destination, true)))
}
_, _ = w.WriteString(`" alt="`)
- _, _ = w.Write(n.Text(source))
+ _, _ = w.Write(util.EscapeHTML(n.Text(source)))
_ = w.WriteByte('"')
if n.Title != nil {
_, _ = w.WriteString(` title="`)
@@ -669,8 +676,13 @@ type Writer interface {
// RawWrite writes the given source to writer without resolving references and
// unescaping backslash escaped characters.
RawWrite(writer util.BufWriter, source []byte)
+
+ // SecureWrite writes the given source to writer with replacing insecure characters.
+ SecureWrite(writer util.BufWriter, source []byte)
}
+var replacementCharacter = []byte("\ufffd")
+
type defaultWriter struct {
}
@@ -685,6 +697,23 @@ func escapeRune(writer util.BufWriter, r rune) {
_, _ = writer.WriteRune(util.ToValidRune(r))
}
+func (d *defaultWriter) SecureWrite(writer util.BufWriter, source []byte) {
+ n := 0
+ l := len(source)
+ for i := 0; i < l; i++ {
+ if source[i] == '\u0000' {
+ _, _ = writer.Write(source[i-n : i])
+ n = 0
+ _, _ = writer.Write(replacementCharacter)
+ continue
+ }
+ n++
+ }
+ if n != 0 {
+ _, _ = writer.Write(source[l-n:])
+ }
+}
+
func (d *defaultWriter) RawWrite(writer util.BufWriter, source []byte) {
n := 0
l := len(source)
@@ -718,6 +747,13 @@ func (d *defaultWriter) Write(writer util.BufWriter, source []byte) {
continue
}
}
+ if c == '\x00' {
+ d.RawWrite(writer, source[n:i])
+ d.RawWrite(writer, replacementCharacter)
+ n = i + 1
+ escaped = false
+ continue
+ }
if c == '&' {
pos := i
next := i + 1
@@ -729,7 +765,7 @@ func (d *defaultWriter) Write(writer util.BufWriter, source []byte) {
if nnext < limit && nc == 'x' || nc == 'X' {
start := nnext + 1
i, ok = util.ReadWhile(source, [2]int{start, limit}, util.IsHexDecimal)
- if ok && i < limit && source[i] == ';' {
+ if ok && i < limit && source[i] == ';' && i-start < 7 {
v, _ := strconv.ParseUint(util.BytesToReadOnlyString(source[start:i]), 16, 32)
d.RawWrite(writer, source[n:pos])
n = i + 1
@@ -741,7 +777,7 @@ func (d *defaultWriter) Write(writer util.BufWriter, source []byte) {
start := nnext
i, ok = util.ReadWhile(source, [2]int{start, limit}, util.IsNumeric)
if ok && i < limit && i-start < 8 && source[i] == ';' {
- v, _ := strconv.ParseUint(util.BytesToReadOnlyString(source[start:i]), 0, 32)
+ v, _ := strconv.ParseUint(util.BytesToReadOnlyString(source[start:i]), 10, 32)
d.RawWrite(writer, source[n:pos])
n = i + 1
escapeRune(writer, rune(v))
@@ -783,6 +819,7 @@ var bPng = []byte("png;")
var bGif = []byte("gif;")
var bJpeg = []byte("jpeg;")
var bWebp = []byte("webp;")
+var bSvg = []byte("svg;")
var bJs = []byte("javascript:")
var bVb = []byte("vbscript:")
var bFile = []byte("file:")
@@ -794,7 +831,8 @@ func IsDangerousURL(url []byte) bool {
if bytes.HasPrefix(url, bDataImage) && len(url) >= 11 {
v := url[11:]
if bytes.HasPrefix(v, bPng) || bytes.HasPrefix(v, bGif) ||
- bytes.HasPrefix(v, bJpeg) || bytes.HasPrefix(v, bWebp) {
+ bytes.HasPrefix(v, bJpeg) || bytes.HasPrefix(v, bWebp) ||
+ bytes.HasPrefix(v, bSvg) {
return false
}
return true
diff --git a/vendor/github.com/yuin/goldmark/text/reader.go b/vendor/github.com/yuin/goldmark/text/reader.go
index df25e5457..319f1c8b8 100644
--- a/vendor/github.com/yuin/goldmark/text/reader.go
+++ b/vendor/github.com/yuin/goldmark/text/reader.go
@@ -70,6 +70,28 @@ type Reader interface {
// Match performs regular expression searching to current line.
FindSubMatch(reg *regexp.Regexp) [][]byte
+
+ // FindClosure finds corresponding closure.
+ FindClosure(opener, closer byte, options FindClosureOptions) (*Segments, bool)
+}
+
+// FindClosureOptions is options for Reader.FindClosure
+type FindClosureOptions struct {
+ // CodeSpan is a flag for the FindClosure. If this is set to true,
+ // FindClosure ignores closers in codespans.
+ CodeSpan bool
+
+ // Nesting is a flag for the FindClosure. If this is set to true,
+ // FindClosure allows nesting.
+ Nesting bool
+
+ // Newline is a flag for the FindClosure. If this is set to true,
+ // FindClosure searches for a closer over multiple lines.
+ Newline bool
+
+ // Advance is a flag for the FindClosure. If this is set to true,
+ // FindClosure advances pointers when closer is found.
+ Advance bool
}
type reader struct {
@@ -92,6 +114,10 @@ func NewReader(source []byte) Reader {
return r
}
+func (r *reader) FindClosure(opener, closer byte, options FindClosureOptions) (*Segments, bool) {
+ return findClosureReader(r, opener, closer, options)
+}
+
func (r *reader) ResetPosition() {
r.line = -1
r.head = 0
@@ -272,6 +298,10 @@ func NewBlockReader(source []byte, segments *Segments) BlockReader {
return r
}
+func (r *blockReader) FindClosure(opener, closer byte, options FindClosureOptions) (*Segments, bool) {
+ return findClosureReader(r, opener, closer, options)
+}
+
func (r *blockReader) ResetPosition() {
r.line = -1
r.head = 0
@@ -541,3 +571,83 @@ func readRuneReader(r Reader) (rune, int, error) {
r.Advance(size)
return rn, size, nil
}
+
+func findClosureReader(r Reader, opener, closer byte, opts FindClosureOptions) (*Segments, bool) {
+ opened := 1
+ codeSpanOpener := 0
+ closed := false
+ orgline, orgpos := r.Position()
+ var ret *Segments
+
+ for {
+ bs, seg := r.PeekLine()
+ if bs == nil {
+ goto end
+ }
+ i := 0
+ for i < len(bs) {
+ c := bs[i]
+ if opts.CodeSpan && codeSpanOpener != 0 && c == '`' {
+ codeSpanCloser := 0
+ for ; i < len(bs); i++ {
+ if bs[i] == '`' {
+ codeSpanCloser++
+ } else {
+ i--
+ break
+ }
+ }
+ if codeSpanCloser == codeSpanOpener {
+ codeSpanOpener = 0
+ }
+ } else if codeSpanOpener == 0 && c == '\\' && i < len(bs)-1 && util.IsPunct(bs[i+1]) {
+ i += 2
+ continue
+ } else if opts.CodeSpan && codeSpanOpener == 0 && c == '`' {
+ for ; i < len(bs); i++ {
+ if bs[i] == '`' {
+ codeSpanOpener++
+ } else {
+ i--
+ break
+ }
+ }
+ } else if (opts.CodeSpan && codeSpanOpener == 0) || !opts.CodeSpan {
+ if c == closer {
+ opened--
+ if opened == 0 {
+ if ret == nil {
+ ret = NewSegments()
+ }
+ ret.Append(seg.WithStop(seg.Start + i))
+ r.Advance(i + 1)
+ closed = true
+ goto end
+ }
+ } else if c == opener {
+ if !opts.Nesting {
+ goto end
+ }
+ opened++
+ }
+ }
+ i++
+ }
+ if !opts.Newline {
+ goto end
+ }
+ r.AdvanceLine()
+ if ret == nil {
+ ret = NewSegments()
+ }
+ ret.Append(seg)
+ }
+end:
+ if !opts.Advance {
+ r.SetPosition(orgline, orgpos)
+ }
+ if closed {
+ return ret, true
+ }
+ return nil, false
+}
diff --git a/vendor/github.com/yuin/goldmark/util/unicode_case_folding.go b/vendor/github.com/yuin/goldmark/util/unicode_case_folding.go
index f66ee7c43..f0e6aa4b8 100644
--- a/vendor/github.com/yuin/goldmark/util/unicode_case_folding.go
+++ b/vendor/github.com/yuin/goldmark/util/unicode_case_folding.go
@@ -1,1491 +1,1534 @@
package util
-var unicodeCaseFoldings = map[rune][]rune{
- 0x41: []int32{97},
- 0x42: []int32{98},
- 0x43: []int32{99},
- 0x44: []int32{100},
- 0x45: []int32{101},
- 0x46: []int32{102},
- 0x47: []int32{103},
- 0x48: []int32{104},
- 0x49: []int32{105},
- 0x4a: []int32{106},
- 0x4b: []int32{107},
- 0x4c: []int32{108},
- 0x4d: []int32{109},
- 0x4e: []int32{110},
- 0x4f: []int32{111},
- 0x50: []int32{112},
- 0x51: []int32{113},
- 0x52: []int32{114},
- 0x53: []int32{115},
- 0x54: []int32{116},
- 0x55: []int32{117},
- 0x56: []int32{118},
- 0x57: []int32{119},
- 0x58: []int32{120},
- 0x59: []int32{121},
- 0x5a: []int32{122},
- 0xb5: []int32{956},
- 0xc0: []int32{224},
- 0xc1: []int32{225},
- 0xc2: []int32{226},
- 0xc3: []int32{227},
- 0xc4: []int32{228},
- 0xc5: []int32{229},
- 0xc6: []int32{230},
- 0xc7: []int32{231},
- 0xc8: []int32{232},
- 0xc9: []int32{233},
- 0xca: []int32{234},
- 0xcb: []int32{235},
- 0xcc: []int32{236},
- 0xcd: []int32{237},
- 0xce: []int32{238},
- 0xcf: []int32{239},
- 0xd0: []int32{240},
- 0xd1: []int32{241},
- 0xd2: []int32{242},
- 0xd3: []int32{243},
- 0xd4: []int32{244},
- 0xd5: []int32{245},
- 0xd6: []int32{246},
- 0xd8: []int32{248},
- 0xd9: []int32{249},
- 0xda: []int32{250},
- 0xdb: []int32{251},
- 0xdc: []int32{252},
- 0xdd: []int32{253},
- 0xde: []int32{254},
- 0xdf: []int32{115, 115},
- 0x100: []int32{257},
- 0x102: []int32{259},
- 0x104: []int32{261},
- 0x106: []int32{263},
- 0x108: []int32{265},
- 0x10a: []int32{267},
- 0x10c: []int32{269},
- 0x10e: []int32{271},
- 0x110: []int32{273},
- 0x112: []int32{275},
- 0x114: []int32{277},
- 0x116: []int32{279},
- 0x118: []int32{281},
- 0x11a: []int32{283},
- 0x11c: []int32{285},
- 0x11e: []int32{287},
- 0x120: []int32{289},
- 0x122: []int32{291},
- 0x124: []int32{293},
- 0x126: []int32{295},
- 0x128: []int32{297},
- 0x12a: []int32{299},
- 0x12c: []int32{301},
- 0x12e: []int32{303},
- 0x130: []int32{105, 775},
- 0x132: []int32{307},
- 0x134: []int32{309},
- 0x136: []int32{311},
- 0x139: []int32{314},
- 0x13b: []int32{316},
- 0x13d: []int32{318},
- 0x13f: []int32{320},
- 0x141: []int32{322},
- 0x143: []int32{324},
- 0x145: []int32{326},
- 0x147: []int32{328},
- 0x149: []int32{700, 110},
- 0x14a: []int32{331},
- 0x14c: []int32{333},
- 0x14e: []int32{335},
- 0x150: []int32{337},
- 0x152: []int32{339},
- 0x154: []int32{341},
- 0x156: []int32{343},
- 0x158: []int32{345},
- 0x15a: []int32{347},
- 0x15c: []int32{349},
- 0x15e: []int32{351},
- 0x160: []int32{353},
- 0x162: []int32{355},
- 0x164: []int32{357},
- 0x166: []int32{359},
- 0x168: []int32{361},
- 0x16a: []int32{363},
- 0x16c: []int32{365},
- 0x16e: []int32{367},
- 0x170: []int32{369},
- 0x172: []int32{371},
- 0x174: []int32{373},
- 0x176: []int32{375},
- 0x178: []int32{255},
- 0x179: []int32{378},
- 0x17b: []int32{380},
- 0x17d: []int32{382},
- 0x17f: []int32{115},
- 0x181: []int32{595},
- 0x182: []int32{387},
- 0x184: []int32{389},
- 0x186: []int32{596},
- 0x187: []int32{392},
- 0x189: []int32{598},
- 0x18a: []int32{599},
- 0x18b: []int32{396},
- 0x18e: []int32{477},
- 0x18f: []int32{601},
- 0x190: []int32{603},
- 0x191: []int32{402},
- 0x193: []int32{608},
- 0x194: []int32{611},
- 0x196: []int32{617},
- 0x197: []int32{616},
- 0x198: []int32{409},
- 0x19c: []int32{623},
- 0x19d: []int32{626},
- 0x19f: []int32{629},
- 0x1a0: []int32{417},
- 0x1a2: []int32{419},
- 0x1a4: []int32{421},
- 0x1a6: []int32{640},
- 0x1a7: []int32{424},
- 0x1a9: []int32{643},
- 0x1ac: []int32{429},
- 0x1ae: []int32{648},
- 0x1af: []int32{432},
- 0x1b1: []int32{650},
- 0x1b2: []int32{651},
- 0x1b3: []int32{436},
- 0x1b5: []int32{438},
- 0x1b7: []int32{658},
- 0x1b8: []int32{441},
- 0x1bc: []int32{445},
- 0x1c4: []int32{454},
- 0x1c5: []int32{454},
- 0x1c7: []int32{457},
- 0x1c8: []int32{457},
- 0x1ca: []int32{460},
- 0x1cb: []int32{460},
- 0x1cd: []int32{462},
- 0x1cf: []int32{464},
- 0x1d1: []int32{466},
- 0x1d3: []int32{468},
- 0x1d5: []int32{470},
- 0x1d7: []int32{472},
- 0x1d9: []int32{474},
- 0x1db: []int32{476},
- 0x1de: []int32{479},
- 0x1e0: []int32{481},
- 0x1e2: []int32{483},
- 0x1e4: []int32{485},
- 0x1e6: []int32{487},
- 0x1e8: []int32{489},
- 0x1ea: []int32{491},
- 0x1ec: []int32{493},
- 0x1ee: []int32{495},
- 0x1f0: []int32{106, 780},
- 0x1f1: []int32{499},
- 0x1f2: []int32{499},
- 0x1f4: []int32{501},
- 0x1f6: []int32{405},
- 0x1f7: []int32{447},
- 0x1f8: []int32{505},
- 0x1fa: []int32{507},
- 0x1fc: []int32{509},
- 0x1fe: []int32{511},
- 0x200: []int32{513},
- 0x202: []int32{515},
- 0x204: []int32{517},
- 0x206: []int32{519},
- 0x208: []int32{521},
- 0x20a: []int32{523},
- 0x20c: []int32{525},
- 0x20e: []int32{527},
- 0x210: []int32{529},
- 0x212: []int32{531},
- 0x214: []int32{533},
- 0x216: []int32{535},
- 0x218: []int32{537},
- 0x21a: []int32{539},
- 0x21c: []int32{541},
- 0x21e: []int32{543},
- 0x220: []int32{414},
- 0x222: []int32{547},
- 0x224: []int32{549},
- 0x226: []int32{551},
- 0x228: []int32{553},
- 0x22a: []int32{555},
- 0x22c: []int32{557},
- 0x22e: []int32{559},
- 0x230: []int32{561},
- 0x232: []int32{563},
- 0x23a: []int32{11365},
- 0x23b: []int32{572},
- 0x23d: []int32{410},
- 0x23e: []int32{11366},
- 0x241: []int32{578},
- 0x243: []int32{384},
- 0x244: []int32{649},
- 0x245: []int32{652},
- 0x246: []int32{583},
- 0x248: []int32{585},
- 0x24a: []int32{587},
- 0x24c: []int32{589},
- 0x24e: []int32{591},
- 0x345: []int32{953},
- 0x370: []int32{881},
- 0x372: []int32{883},
- 0x376: []int32{887},
- 0x37f: []int32{1011},
- 0x386: []int32{940},
- 0x388: []int32{941},
- 0x389: []int32{942},
- 0x38a: []int32{943},
- 0x38c: []int32{972},
- 0x38e: []int32{973},
- 0x38f: []int32{974},
- 0x390: []int32{953, 776, 769},
- 0x391: []int32{945},
- 0x392: []int32{946},
- 0x393: []int32{947},
- 0x394: []int32{948},
- 0x395: []int32{949},
- 0x396: []int32{950},
- 0x397: []int32{951},
- 0x398: []int32{952},
- 0x399: []int32{953},
- 0x39a: []int32{954},
- 0x39b: []int32{955},
- 0x39c: []int32{956},
- 0x39d: []int32{957},
- 0x39e: []int32{958},
- 0x39f: []int32{959},
- 0x3a0: []int32{960},
- 0x3a1: []int32{961},
- 0x3a3: []int32{963},
- 0x3a4: []int32{964},
- 0x3a5: []int32{965},
- 0x3a6: []int32{966},
- 0x3a7: []int32{967},
- 0x3a8: []int32{968},
- 0x3a9: []int32{969},
- 0x3aa: []int32{970},
- 0x3ab: []int32{971},
- 0x3b0: []int32{965, 776, 769},
- 0x3c2: []int32{963},
- 0x3cf: []int32{983},
- 0x3d0: []int32{946},
- 0x3d1: []int32{952},
- 0x3d5: []int32{966},
- 0x3d6: []int32{960},
- 0x3d8: []int32{985},
- 0x3da: []int32{987},
- 0x3dc: []int32{989},
- 0x3de: []int32{991},
- 0x3e0: []int32{993},
- 0x3e2: []int32{995},
- 0x3e4: []int32{997},
- 0x3e6: []int32{999},
- 0x3e8: []int32{1001},
- 0x3ea: []int32{1003},
- 0x3ec: []int32{1005},
- 0x3ee: []int32{1007},
- 0x3f0: []int32{954},
- 0x3f1: []int32{961},
- 0x3f4: []int32{952},
- 0x3f5: []int32{949},
- 0x3f7: []int32{1016},
- 0x3f9: []int32{1010},
- 0x3fa: []int32{1019},
- 0x3fd: []int32{891},
- 0x3fe: []int32{892},
- 0x3ff: []int32{893},
- 0x400: []int32{1104},
- 0x401: []int32{1105},
- 0x402: []int32{1106},
- 0x403: []int32{1107},
- 0x404: []int32{1108},
- 0x405: []int32{1109},
- 0x406: []int32{1110},
- 0x407: []int32{1111},
- 0x408: []int32{1112},
- 0x409: []int32{1113},
- 0x40a: []int32{1114},
- 0x40b: []int32{1115},
- 0x40c: []int32{1116},
- 0x40d: []int32{1117},
- 0x40e: []int32{1118},
- 0x40f: []int32{1119},
- 0x410: []int32{1072},
- 0x411: []int32{1073},
- 0x412: []int32{1074},
- 0x413: []int32{1075},
- 0x414: []int32{1076},
- 0x415: []int32{1077},
- 0x416: []int32{1078},
- 0x417: []int32{1079},
- 0x418: []int32{1080},
- 0x419: []int32{1081},
- 0x41a: []int32{1082},
- 0x41b: []int32{1083},
- 0x41c: []int32{1084},
- 0x41d: []int32{1085},
- 0x41e: []int32{1086},
- 0x41f: []int32{1087},
- 0x420: []int32{1088},
- 0x421: []int32{1089},
- 0x422: []int32{1090},
- 0x423: []int32{1091},
- 0x424: []int32{1092},
- 0x425: []int32{1093},
- 0x426: []int32{1094},
- 0x427: []int32{1095},
- 0x428: []int32{1096},
- 0x429: []int32{1097},
- 0x42a: []int32{1098},
- 0x42b: []int32{1099},
- 0x42c: []int32{1100},
- 0x42d: []int32{1101},
- 0x42e: []int32{1102},
- 0x42f: []int32{1103},
- 0x460: []int32{1121},
- 0x462: []int32{1123},
- 0x464: []int32{1125},
- 0x466: []int32{1127},
- 0x468: []int32{1129},
- 0x46a: []int32{1131},
- 0x46c: []int32{1133},
- 0x46e: []int32{1135},
- 0x470: []int32{1137},
- 0x472: []int32{1139},
- 0x474: []int32{1141},
- 0x476: []int32{1143},
- 0x478: []int32{1145},
- 0x47a: []int32{1147},
- 0x47c: []int32{1149},
- 0x47e: []int32{1151},
- 0x480: []int32{1153},
- 0x48a: []int32{1163},
- 0x48c: []int32{1165},
- 0x48e: []int32{1167},
- 0x490: []int32{1169},
- 0x492: []int32{1171},
- 0x494: []int32{1173},
- 0x496: []int32{1175},
- 0x498: []int32{1177},
- 0x49a: []int32{1179},
- 0x49c: []int32{1181},
- 0x49e: []int32{1183},
- 0x4a0: []int32{1185},
- 0x4a2: []int32{1187},
- 0x4a4: []int32{1189},
- 0x4a6: []int32{1191},
- 0x4a8: []int32{1193},
- 0x4aa: []int32{1195},
- 0x4ac: []int32{1197},
- 0x4ae: []int32{1199},
- 0x4b0: []int32{1201},
- 0x4b2: []int32{1203},
- 0x4b4: []int32{1205},
- 0x4b6: []int32{1207},
- 0x4b8: []int32{1209},
- 0x4ba: []int32{1211},
- 0x4bc: []int32{1213},
- 0x4be: []int32{1215},
- 0x4c0: []int32{1231},
- 0x4c1: []int32{1218},
- 0x4c3: []int32{1220},
- 0x4c5: []int32{1222},
- 0x4c7: []int32{1224},
- 0x4c9: []int32{1226},
- 0x4cb: []int32{1228},
- 0x4cd: []int32{1230},
- 0x4d0: []int32{1233},
- 0x4d2: []int32{1235},
- 0x4d4: []int32{1237},
- 0x4d6: []int32{1239},
- 0x4d8: []int32{1241},
- 0x4da: []int32{1243},
- 0x4dc: []int32{1245},
- 0x4de: []int32{1247},
- 0x4e0: []int32{1249},
- 0x4e2: []int32{1251},
- 0x4e4: []int32{1253},
- 0x4e6: []int32{1255},
- 0x4e8: []int32{1257},
- 0x4ea: []int32{1259},
- 0x4ec: []int32{1261},
- 0x4ee: []int32{1263},
- 0x4f0: []int32{1265},
- 0x4f2: []int32{1267},
- 0x4f4: []int32{1269},
- 0x4f6: []int32{1271},
- 0x4f8: []int32{1273},
- 0x4fa: []int32{1275},
- 0x4fc: []int32{1277},
- 0x4fe: []int32{1279},
- 0x500: []int32{1281},
- 0x502: []int32{1283},
- 0x504: []int32{1285},
- 0x506: []int32{1287},
- 0x508: []int32{1289},
- 0x50a: []int32{1291},
- 0x50c: []int32{1293},
- 0x50e: []int32{1295},
- 0x510: []int32{1297},
- 0x512: []int32{1299},
- 0x514: []int32{1301},
- 0x516: []int32{1303},
- 0x518: []int32{1305},
- 0x51a: []int32{1307},
- 0x51c: []int32{1309},
- 0x51e: []int32{1311},
- 0x520: []int32{1313},
- 0x522: []int32{1315},
- 0x524: []int32{1317},
- 0x526: []int32{1319},
- 0x528: []int32{1321},
- 0x52a: []int32{1323},
- 0x52c: []int32{1325},
- 0x52e: []int32{1327},
- 0x531: []int32{1377},
- 0x532: []int32{1378},
- 0x533: []int32{1379},
- 0x534: []int32{1380},
- 0x535: []int32{1381},
- 0x536: []int32{1382},
- 0x537: []int32{1383},
- 0x538: []int32{1384},
- 0x539: []int32{1385},
- 0x53a: []int32{1386},
- 0x53b: []int32{1387},
- 0x53c: []int32{1388},
- 0x53d: []int32{1389},
- 0x53e: []int32{1390},
- 0x53f: []int32{1391},
- 0x540: []int32{1392},
- 0x541: []int32{1393},
- 0x542: []int32{1394},
- 0x543: []int32{1395},
- 0x544: []int32{1396},
- 0x545: []int32{1397},
- 0x546: []int32{1398},
- 0x547: []int32{1399},
- 0x548: []int32{1400},
- 0x549: []int32{1401},
- 0x54a: []int32{1402},
- 0x54b: []int32{1403},
- 0x54c: []int32{1404},
- 0x54d: []int32{1405},
- 0x54e: []int32{1406},
- 0x54f: []int32{1407},
- 0x550: []int32{1408},
- 0x551: []int32{1409},
- 0x552: []int32{1410},
- 0x553: []int32{1411},
- 0x554: []int32{1412},
- 0x555: []int32{1413},
- 0x556: []int32{1414},
- 0x587: []int32{1381, 1410},
- 0x10a0: []int32{11520},
- 0x10a1: []int32{11521},
- 0x10a2: []int32{11522},
- 0x10a3: []int32{11523},
- 0x10a4: []int32{11524},
- 0x10a5: []int32{11525},
- 0x10a6: []int32{11526},
- 0x10a7: []int32{11527},
- 0x10a8: []int32{11528},
- 0x10a9: []int32{11529},
- 0x10aa: []int32{11530},
- 0x10ab: []int32{11531},
- 0x10ac: []int32{11532},
- 0x10ad: []int32{11533},
- 0x10ae: []int32{11534},
- 0x10af: []int32{11535},
- 0x10b0: []int32{11536},
- 0x10b1: []int32{11537},
- 0x10b2: []int32{11538},
- 0x10b3: []int32{11539},
- 0x10b4: []int32{11540},
- 0x10b5: []int32{11541},
- 0x10b6: []int32{11542},
- 0x10b7: []int32{11543},
- 0x10b8: []int32{11544},
- 0x10b9: []int32{11545},
- 0x10ba: []int32{11546},
- 0x10bb: []int32{11547},
- 0x10bc: []int32{11548},
- 0x10bd: []int32{11549},
- 0x10be: []int32{11550},
- 0x10bf: []int32{11551},
- 0x10c0: []int32{11552},
- 0x10c1: []int32{11553},
- 0x10c2: []int32{11554},
- 0x10c3: []int32{11555},
- 0x10c4: []int32{11556},
- 0x10c5: []int32{11557},
- 0x10c7: []int32{11559},
- 0x10cd: []int32{11565},
- 0x13f8: []int32{5104},
- 0x13f9: []int32{5105},
- 0x13fa: []int32{5106},
- 0x13fb: []int32{5107},
- 0x13fc: []int32{5108},
- 0x13fd: []int32{5109},
- 0x1c80: []int32{1074},
- 0x1c81: []int32{1076},
- 0x1c82: []int32{1086},
- 0x1c83: []int32{1089},
- 0x1c84: []int32{1090},
- 0x1c85: []int32{1090},
- 0x1c86: []int32{1098},
- 0x1c87: []int32{1123},
- 0x1c88: []int32{42571},
- 0x1c90: []int32{4304},
- 0x1c91: []int32{4305},
- 0x1c92: []int32{4306},
- 0x1c93: []int32{4307},
- 0x1c94: []int32{4308},
- 0x1c95: []int32{4309},
- 0x1c96: []int32{4310},
- 0x1c97: []int32{4311},
- 0x1c98: []int32{4312},
- 0x1c99: []int32{4313},
- 0x1c9a: []int32{4314},
- 0x1c9b: []int32{4315},
- 0x1c9c: []int32{4316},
- 0x1c9d: []int32{4317},
- 0x1c9e: []int32{4318},
- 0x1c9f: []int32{4319},
- 0x1ca0: []int32{4320},
- 0x1ca1: []int32{4321},
- 0x1ca2: []int32{4322},
- 0x1ca3: []int32{4323},
- 0x1ca4: []int32{4324},
- 0x1ca5: []int32{4325},
- 0x1ca6: []int32{4326},
- 0x1ca7: []int32{4327},
- 0x1ca8: []int32{4328},
- 0x1ca9: []int32{4329},
- 0x1caa: []int32{4330},
- 0x1cab: []int32{4331},
- 0x1cac: []int32{4332},
- 0x1cad: []int32{4333},
- 0x1cae: []int32{4334},
- 0x1caf: []int32{4335},
- 0x1cb0: []int32{4336},
- 0x1cb1: []int32{4337},
- 0x1cb2: []int32{4338},
- 0x1cb3: []int32{4339},
- 0x1cb4: []int32{4340},
- 0x1cb5: []int32{4341},
- 0x1cb6: []int32{4342},
- 0x1cb7: []int32{4343},
- 0x1cb8: []int32{4344},
- 0x1cb9: []int32{4345},
- 0x1cba: []int32{4346},
- 0x1cbd: []int32{4349},
- 0x1cbe: []int32{4350},
- 0x1cbf: []int32{4351},
- 0x1e00: []int32{7681},
- 0x1e02: []int32{7683},
- 0x1e04: []int32{7685},
- 0x1e06: []int32{7687},
- 0x1e08: []int32{7689},
- 0x1e0a: []int32{7691},
- 0x1e0c: []int32{7693},
- 0x1e0e: []int32{7695},
- 0x1e10: []int32{7697},
- 0x1e12: []int32{7699},
- 0x1e14: []int32{7701},
- 0x1e16: []int32{7703},
- 0x1e18: []int32{7705},
- 0x1e1a: []int32{7707},
- 0x1e1c: []int32{7709},
- 0x1e1e: []int32{7711},
- 0x1e20: []int32{7713},
- 0x1e22: []int32{7715},
- 0x1e24: []int32{7717},
- 0x1e26: []int32{7719},
- 0x1e28: []int32{7721},
- 0x1e2a: []int32{7723},
- 0x1e2c: []int32{7725},
- 0x1e2e: []int32{7727},
- 0x1e30: []int32{7729},
- 0x1e32: []int32{7731},
- 0x1e34: []int32{7733},
- 0x1e36: []int32{7735},
- 0x1e38: []int32{7737},
- 0x1e3a: []int32{7739},
- 0x1e3c: []int32{7741},
- 0x1e3e: []int32{7743},
- 0x1e40: []int32{7745},
- 0x1e42: []int32{7747},
- 0x1e44: []int32{7749},
- 0x1e46: []int32{7751},
- 0x1e48: []int32{7753},
- 0x1e4a: []int32{7755},
- 0x1e4c: []int32{7757},
- 0x1e4e: []int32{7759},
- 0x1e50: []int32{7761},
- 0x1e52: []int32{7763},
- 0x1e54: []int32{7765},
- 0x1e56: []int32{7767},
- 0x1e58: []int32{7769},
- 0x1e5a: []int32{7771},
- 0x1e5c: []int32{7773},
- 0x1e5e: []int32{7775},
- 0x1e60: []int32{7777},
- 0x1e62: []int32{7779},
- 0x1e64: []int32{7781},
- 0x1e66: []int32{7783},
- 0x1e68: []int32{7785},
- 0x1e6a: []int32{7787},
- 0x1e6c: []int32{7789},
- 0x1e6e: []int32{7791},
- 0x1e70: []int32{7793},
- 0x1e72: []int32{7795},
- 0x1e74: []int32{7797},
- 0x1e76: []int32{7799},
- 0x1e78: []int32{7801},
- 0x1e7a: []int32{7803},
- 0x1e7c: []int32{7805},
- 0x1e7e: []int32{7807},
- 0x1e80: []int32{7809},
- 0x1e82: []int32{7811},
- 0x1e84: []int32{7813},
- 0x1e86: []int32{7815},
- 0x1e88: []int32{7817},
- 0x1e8a: []int32{7819},
- 0x1e8c: []int32{7821},
- 0x1e8e: []int32{7823},
- 0x1e90: []int32{7825},
- 0x1e92: []int32{7827},
- 0x1e94: []int32{7829},
- 0x1e96: []int32{104, 817},
- 0x1e97: []int32{116, 776},
- 0x1e98: []int32{119, 778},
- 0x1e99: []int32{121, 778},
- 0x1e9a: []int32{97, 702},
- 0x1e9b: []int32{7777},
- 0x1e9e: []int32{115, 115},
- 0x1ea0: []int32{7841},
- 0x1ea2: []int32{7843},
- 0x1ea4: []int32{7845},
- 0x1ea6: []int32{7847},
- 0x1ea8: []int32{7849},
- 0x1eaa: []int32{7851},
- 0x1eac: []int32{7853},
- 0x1eae: []int32{7855},
- 0x1eb0: []int32{7857},
- 0x1eb2: []int32{7859},
- 0x1eb4: []int32{7861},
- 0x1eb6: []int32{7863},
- 0x1eb8: []int32{7865},
- 0x1eba: []int32{7867},
- 0x1ebc: []int32{7869},
- 0x1ebe: []int32{7871},
- 0x1ec0: []int32{7873},
- 0x1ec2: []int32{7875},
- 0x1ec4: []int32{7877},
- 0x1ec6: []int32{7879},
- 0x1ec8: []int32{7881},
- 0x1eca: []int32{7883},
- 0x1ecc: []int32{7885},
- 0x1ece: []int32{7887},
- 0x1ed0: []int32{7889},
- 0x1ed2: []int32{7891},
- 0x1ed4: []int32{7893},
- 0x1ed6: []int32{7895},
- 0x1ed8: []int32{7897},
- 0x1eda: []int32{7899},
- 0x1edc: []int32{7901},
- 0x1ede: []int32{7903},
- 0x1ee0: []int32{7905},
- 0x1ee2: []int32{7907},
- 0x1ee4: []int32{7909},
- 0x1ee6: []int32{7911},
- 0x1ee8: []int32{7913},
- 0x1eea: []int32{7915},
- 0x1eec: []int32{7917},
- 0x1eee: []int32{7919},
- 0x1ef0: []int32{7921},
- 0x1ef2: []int32{7923},
- 0x1ef4: []int32{7925},
- 0x1ef6: []int32{7927},
- 0x1ef8: []int32{7929},
- 0x1efa: []int32{7931},
- 0x1efc: []int32{7933},
- 0x1efe: []int32{7935},
- 0x1f08: []int32{7936},
- 0x1f09: []int32{7937},
- 0x1f0a: []int32{7938},
- 0x1f0b: []int32{7939},
- 0x1f0c: []int32{7940},
- 0x1f0d: []int32{7941},
- 0x1f0e: []int32{7942},
- 0x1f0f: []int32{7943},
- 0x1f18: []int32{7952},
- 0x1f19: []int32{7953},
- 0x1f1a: []int32{7954},
- 0x1f1b: []int32{7955},
- 0x1f1c: []int32{7956},
- 0x1f1d: []int32{7957},
- 0x1f28: []int32{7968},
- 0x1f29: []int32{7969},
- 0x1f2a: []int32{7970},
- 0x1f2b: []int32{7971},
- 0x1f2c: []int32{7972},
- 0x1f2d: []int32{7973},
- 0x1f2e: []int32{7974},
- 0x1f2f: []int32{7975},
- 0x1f38: []int32{7984},
- 0x1f39: []int32{7985},
- 0x1f3a: []int32{7986},
- 0x1f3b: []int32{7987},
- 0x1f3c: []int32{7988},
- 0x1f3d: []int32{7989},
- 0x1f3e: []int32{7990},
- 0x1f3f: []int32{7991},
- 0x1f48: []int32{8000},
- 0x1f49: []int32{8001},
- 0x1f4a: []int32{8002},
- 0x1f4b: []int32{8003},
- 0x1f4c: []int32{8004},
- 0x1f4d: []int32{8005},
- 0x1f50: []int32{965, 787},
- 0x1f52: []int32{965, 787, 768},
- 0x1f54: []int32{965, 787, 769},
- 0x1f56: []int32{965, 787, 834},
- 0x1f59: []int32{8017},
- 0x1f5b: []int32{8019},
- 0x1f5d: []int32{8021},
- 0x1f5f: []int32{8023},
- 0x1f68: []int32{8032},
- 0x1f69: []int32{8033},
- 0x1f6a: []int32{8034},
- 0x1f6b: []int32{8035},
- 0x1f6c: []int32{8036},
- 0x1f6d: []int32{8037},
- 0x1f6e: []int32{8038},
- 0x1f6f: []int32{8039},
- 0x1f80: []int32{7936, 953},
- 0x1f81: []int32{7937, 953},
- 0x1f82: []int32{7938, 953},
- 0x1f83: []int32{7939, 953},
- 0x1f84: []int32{7940, 953},
- 0x1f85: []int32{7941, 953},
- 0x1f86: []int32{7942, 953},
- 0x1f87: []int32{7943, 953},
- 0x1f88: []int32{7936, 953},
- 0x1f89: []int32{7937, 953},
- 0x1f8a: []int32{7938, 953},
- 0x1f8b: []int32{7939, 953},
- 0x1f8c: []int32{7940, 953},
- 0x1f8d: []int32{7941, 953},
- 0x1f8e: []int32{7942, 953},
- 0x1f8f: []int32{7943, 953},
- 0x1f90: []int32{7968, 953},
- 0x1f91: []int32{7969, 953},
- 0x1f92: []int32{7970, 953},
- 0x1f93: []int32{7971, 953},
- 0x1f94: []int32{7972, 953},
- 0x1f95: []int32{7973, 953},
- 0x1f96: []int32{7974, 953},
- 0x1f97: []int32{7975, 953},
- 0x1f98: []int32{7968, 953},
- 0x1f99: []int32{7969, 953},
- 0x1f9a: []int32{7970, 953},
- 0x1f9b: []int32{7971, 953},
- 0x1f9c: []int32{7972, 953},
- 0x1f9d: []int32{7973, 953},
- 0x1f9e: []int32{7974, 953},
- 0x1f9f: []int32{7975, 953},
- 0x1fa0: []int32{8032, 953},
- 0x1fa1: []int32{8033, 953},
- 0x1fa2: []int32{8034, 953},
- 0x1fa3: []int32{8035, 953},
- 0x1fa4: []int32{8036, 953},
- 0x1fa5: []int32{8037, 953},
- 0x1fa6: []int32{8038, 953},
- 0x1fa7: []int32{8039, 953},
- 0x1fa8: []int32{8032, 953},
- 0x1fa9: []int32{8033, 953},
- 0x1faa: []int32{8034, 953},
- 0x1fab: []int32{8035, 953},
- 0x1fac: []int32{8036, 953},
- 0x1fad: []int32{8037, 953},
- 0x1fae: []int32{8038, 953},
- 0x1faf: []int32{8039, 953},
- 0x1fb2: []int32{8048, 953},
- 0x1fb3: []int32{945, 953},
- 0x1fb4: []int32{940, 953},
- 0x1fb6: []int32{945, 834},
- 0x1fb7: []int32{945, 834, 953},
- 0x1fb8: []int32{8112},
- 0x1fb9: []int32{8113},
- 0x1fba: []int32{8048},
- 0x1fbb: []int32{8049},
- 0x1fbc: []int32{945, 953},
- 0x1fbe: []int32{953},
- 0x1fc2: []int32{8052, 953},
- 0x1fc3: []int32{951, 953},
- 0x1fc4: []int32{942, 953},
- 0x1fc6: []int32{951, 834},
- 0x1fc7: []int32{951, 834, 953},
- 0x1fc8: []int32{8050},
- 0x1fc9: []int32{8051},
- 0x1fca: []int32{8052},
- 0x1fcb: []int32{8053},
- 0x1fcc: []int32{951, 953},
- 0x1fd2: []int32{953, 776, 768},
- 0x1fd3: []int32{953, 776, 769},
- 0x1fd6: []int32{953, 834},
- 0x1fd7: []int32{953, 776, 834},
- 0x1fd8: []int32{8144},
- 0x1fd9: []int32{8145},
- 0x1fda: []int32{8054},
- 0x1fdb: []int32{8055},
- 0x1fe2: []int32{965, 776, 768},
- 0x1fe3: []int32{965, 776, 769},
- 0x1fe4: []int32{961, 787},
- 0x1fe6: []int32{965, 834},
- 0x1fe7: []int32{965, 776, 834},
- 0x1fe8: []int32{8160},
- 0x1fe9: []int32{8161},
- 0x1fea: []int32{8058},
- 0x1feb: []int32{8059},
- 0x1fec: []int32{8165},
- 0x1ff2: []int32{8060, 953},
- 0x1ff3: []int32{969, 953},
- 0x1ff4: []int32{974, 953},
- 0x1ff6: []int32{969, 834},
- 0x1ff7: []int32{969, 834, 953},
- 0x1ff8: []int32{8056},
- 0x1ff9: []int32{8057},
- 0x1ffa: []int32{8060},
- 0x1ffb: []int32{8061},
- 0x1ffc: []int32{969, 953},
- 0x2126: []int32{969},
- 0x212a: []int32{107},
- 0x212b: []int32{229},
- 0x2132: []int32{8526},
- 0x2160: []int32{8560},
- 0x2161: []int32{8561},
- 0x2162: []int32{8562},
- 0x2163: []int32{8563},
- 0x2164: []int32{8564},
- 0x2165: []int32{8565},
- 0x2166: []int32{8566},
- 0x2167: []int32{8567},
- 0x2168: []int32{8568},
- 0x2169: []int32{8569},
- 0x216a: []int32{8570},
- 0x216b: []int32{8571},
- 0x216c: []int32{8572},
- 0x216d: []int32{8573},
- 0x216e: []int32{8574},
- 0x216f: []int32{8575},
- 0x2183: []int32{8580},
- 0x24b6: []int32{9424},
- 0x24b7: []int32{9425},
- 0x24b8: []int32{9426},
- 0x24b9: []int32{9427},
- 0x24ba: []int32{9428},
- 0x24bb: []int32{9429},
- 0x24bc: []int32{9430},
- 0x24bd: []int32{9431},
- 0x24be: []int32{9432},
- 0x24bf: []int32{9433},
- 0x24c0: []int32{9434},
- 0x24c1: []int32{9435},
- 0x24c2: []int32{9436},
- 0x24c3: []int32{9437},
- 0x24c4: []int32{9438},
- 0x24c5: []int32{9439},
- 0x24c6: []int32{9440},
- 0x24c7: []int32{9441},
- 0x24c8: []int32{9442},
- 0x24c9: []int32{9443},
- 0x24ca: []int32{9444},
- 0x24cb: []int32{9445},
- 0x24cc: []int32{9446},
- 0x24cd: []int32{9447},
- 0x24ce: []int32{9448},
- 0x24cf: []int32{9449},
- 0x2c00: []int32{11312},
- 0x2c01: []int32{11313},
- 0x2c02: []int32{11314},
- 0x2c03: []int32{11315},
- 0x2c04: []int32{11316},
- 0x2c05: []int32{11317},
- 0x2c06: []int32{11318},
- 0x2c07: []int32{11319},
- 0x2c08: []int32{11320},
- 0x2c09: []int32{11321},
- 0x2c0a: []int32{11322},
- 0x2c0b: []int32{11323},
- 0x2c0c: []int32{11324},
- 0x2c0d: []int32{11325},
- 0x2c0e: []int32{11326},
- 0x2c0f: []int32{11327},
- 0x2c10: []int32{11328},
- 0x2c11: []int32{11329},
- 0x2c12: []int32{11330},
- 0x2c13: []int32{11331},
- 0x2c14: []int32{11332},
- 0x2c15: []int32{11333},
- 0x2c16: []int32{11334},
- 0x2c17: []int32{11335},
- 0x2c18: []int32{11336},
- 0x2c19: []int32{11337},
- 0x2c1a: []int32{11338},
- 0x2c1b: []int32{11339},
- 0x2c1c: []int32{11340},
- 0x2c1d: []int32{11341},
- 0x2c1e: []int32{11342},
- 0x2c1f: []int32{11343},
- 0x2c20: []int32{11344},
- 0x2c21: []int32{11345},
- 0x2c22: []int32{11346},
- 0x2c23: []int32{11347},
- 0x2c24: []int32{11348},
- 0x2c25: []int32{11349},
- 0x2c26: []int32{11350},
- 0x2c27: []int32{11351},
- 0x2c28: []int32{11352},
- 0x2c29: []int32{11353},
- 0x2c2a: []int32{11354},
- 0x2c2b: []int32{11355},
- 0x2c2c: []int32{11356},
- 0x2c2d: []int32{11357},
- 0x2c2e: []int32{11358},
- 0x2c60: []int32{11361},
- 0x2c62: []int32{619},
- 0x2c63: []int32{7549},
- 0x2c64: []int32{637},
- 0x2c67: []int32{11368},
- 0x2c69: []int32{11370},
- 0x2c6b: []int32{11372},
- 0x2c6d: []int32{593},
- 0x2c6e: []int32{625},
- 0x2c6f: []int32{592},
- 0x2c70: []int32{594},
- 0x2c72: []int32{11379},
- 0x2c75: []int32{11382},
- 0x2c7e: []int32{575},
- 0x2c7f: []int32{576},
- 0x2c80: []int32{11393},
- 0x2c82: []int32{11395},
- 0x2c84: []int32{11397},
- 0x2c86: []int32{11399},
- 0x2c88: []int32{11401},
- 0x2c8a: []int32{11403},
- 0x2c8c: []int32{11405},
- 0x2c8e: []int32{11407},
- 0x2c90: []int32{11409},
- 0x2c92: []int32{11411},
- 0x2c94: []int32{11413},
- 0x2c96: []int32{11415},
- 0x2c98: []int32{11417},
- 0x2c9a: []int32{11419},
- 0x2c9c: []int32{11421},
- 0x2c9e: []int32{11423},
- 0x2ca0: []int32{11425},
- 0x2ca2: []int32{11427},
- 0x2ca4: []int32{11429},
- 0x2ca6: []int32{11431},
- 0x2ca8: []int32{11433},
- 0x2caa: []int32{11435},
- 0x2cac: []int32{11437},
- 0x2cae: []int32{11439},
- 0x2cb0: []int32{11441},
- 0x2cb2: []int32{11443},
- 0x2cb4: []int32{11445},
- 0x2cb6: []int32{11447},
- 0x2cb8: []int32{11449},
- 0x2cba: []int32{11451},
- 0x2cbc: []int32{11453},
- 0x2cbe: []int32{11455},
- 0x2cc0: []int32{11457},
- 0x2cc2: []int32{11459},
- 0x2cc4: []int32{11461},
- 0x2cc6: []int32{11463},
- 0x2cc8: []int32{11465},
- 0x2cca: []int32{11467},
- 0x2ccc: []int32{11469},
- 0x2cce: []int32{11471},
- 0x2cd0: []int32{11473},
- 0x2cd2: []int32{11475},
- 0x2cd4: []int32{11477},
- 0x2cd6: []int32{11479},
- 0x2cd8: []int32{11481},
- 0x2cda: []int32{11483},
- 0x2cdc: []int32{11485},
- 0x2cde: []int32{11487},
- 0x2ce0: []int32{11489},
- 0x2ce2: []int32{11491},
- 0x2ceb: []int32{11500},
- 0x2ced: []int32{11502},
- 0x2cf2: []int32{11507},
- 0xa640: []int32{42561},
- 0xa642: []int32{42563},
- 0xa644: []int32{42565},
- 0xa646: []int32{42567},
- 0xa648: []int32{42569},
- 0xa64a: []int32{42571},
- 0xa64c: []int32{42573},
- 0xa64e: []int32{42575},
- 0xa650: []int32{42577},
- 0xa652: []int32{42579},
- 0xa654: []int32{42581},
- 0xa656: []int32{42583},
- 0xa658: []int32{42585},
- 0xa65a: []int32{42587},
- 0xa65c: []int32{42589},
- 0xa65e: []int32{42591},
- 0xa660: []int32{42593},
- 0xa662: []int32{42595},
- 0xa664: []int32{42597},
- 0xa666: []int32{42599},
- 0xa668: []int32{42601},
- 0xa66a: []int32{42603},
- 0xa66c: []int32{42605},
- 0xa680: []int32{42625},
- 0xa682: []int32{42627},
- 0xa684: []int32{42629},
- 0xa686: []int32{42631},
- 0xa688: []int32{42633},
- 0xa68a: []int32{42635},
- 0xa68c: []int32{42637},
- 0xa68e: []int32{42639},
- 0xa690: []int32{42641},
- 0xa692: []int32{42643},
- 0xa694: []int32{42645},
- 0xa696: []int32{42647},
- 0xa698: []int32{42649},
- 0xa69a: []int32{42651},
- 0xa722: []int32{42787},
- 0xa724: []int32{42789},
- 0xa726: []int32{42791},
- 0xa728: []int32{42793},
- 0xa72a: []int32{42795},
- 0xa72c: []int32{42797},
- 0xa72e: []int32{42799},
- 0xa732: []int32{42803},
- 0xa734: []int32{42805},
- 0xa736: []int32{42807},
- 0xa738: []int32{42809},
- 0xa73a: []int32{42811},
- 0xa73c: []int32{42813},
- 0xa73e: []int32{42815},
- 0xa740: []int32{42817},
- 0xa742: []int32{42819},
- 0xa744: []int32{42821},
- 0xa746: []int32{42823},
- 0xa748: []int32{42825},
- 0xa74a: []int32{42827},
- 0xa74c: []int32{42829},
- 0xa74e: []int32{42831},
- 0xa750: []int32{42833},
- 0xa752: []int32{42835},
- 0xa754: []int32{42837},
- 0xa756: []int32{42839},
- 0xa758: []int32{42841},
- 0xa75a: []int32{42843},
- 0xa75c: []int32{42845},
- 0xa75e: []int32{42847},
- 0xa760: []int32{42849},
- 0xa762: []int32{42851},
- 0xa764: []int32{42853},
- 0xa766: []int32{42855},
- 0xa768: []int32{42857},
- 0xa76a: []int32{42859},
- 0xa76c: []int32{42861},
- 0xa76e: []int32{42863},
- 0xa779: []int32{42874},
- 0xa77b: []int32{42876},
- 0xa77d: []int32{7545},
- 0xa77e: []int32{42879},
- 0xa780: []int32{42881},
- 0xa782: []int32{42883},
- 0xa784: []int32{42885},
- 0xa786: []int32{42887},
- 0xa78b: []int32{42892},
- 0xa78d: []int32{613},
- 0xa790: []int32{42897},
- 0xa792: []int32{42899},
- 0xa796: []int32{42903},
- 0xa798: []int32{42905},
- 0xa79a: []int32{42907},
- 0xa79c: []int32{42909},
- 0xa79e: []int32{42911},
- 0xa7a0: []int32{42913},
- 0xa7a2: []int32{42915},
- 0xa7a4: []int32{42917},
- 0xa7a6: []int32{42919},
- 0xa7a8: []int32{42921},
- 0xa7aa: []int32{614},
- 0xa7ab: []int32{604},
- 0xa7ac: []int32{609},
- 0xa7ad: []int32{620},
- 0xa7ae: []int32{618},
- 0xa7b0: []int32{670},
- 0xa7b1: []int32{647},
- 0xa7b2: []int32{669},
- 0xa7b3: []int32{43859},
- 0xa7b4: []int32{42933},
- 0xa7b6: []int32{42935},
- 0xa7b8: []int32{42937},
- 0xa7ba: []int32{42939},
- 0xa7bc: []int32{42941},
- 0xa7be: []int32{42943},
- 0xa7c2: []int32{42947},
- 0xa7c4: []int32{42900},
- 0xa7c5: []int32{642},
- 0xa7c6: []int32{7566},
- 0xab70: []int32{5024},
- 0xab71: []int32{5025},
- 0xab72: []int32{5026},
- 0xab73: []int32{5027},
- 0xab74: []int32{5028},
- 0xab75: []int32{5029},
- 0xab76: []int32{5030},
- 0xab77: []int32{5031},
- 0xab78: []int32{5032},
- 0xab79: []int32{5033},
- 0xab7a: []int32{5034},
- 0xab7b: []int32{5035},
- 0xab7c: []int32{5036},
- 0xab7d: []int32{5037},
- 0xab7e: []int32{5038},
- 0xab7f: []int32{5039},
- 0xab80: []int32{5040},
- 0xab81: []int32{5041},
- 0xab82: []int32{5042},
- 0xab83: []int32{5043},
- 0xab84: []int32{5044},
- 0xab85: []int32{5045},
- 0xab86: []int32{5046},
- 0xab87: []int32{5047},
- 0xab88: []int32{5048},
- 0xab89: []int32{5049},
- 0xab8a: []int32{5050},
- 0xab8b: []int32{5051},
- 0xab8c: []int32{5052},
- 0xab8d: []int32{5053},
- 0xab8e: []int32{5054},
- 0xab8f: []int32{5055},
- 0xab90: []int32{5056},
- 0xab91: []int32{5057},
- 0xab92: []int32{5058},
- 0xab93: []int32{5059},
- 0xab94: []int32{5060},
- 0xab95: []int32{5061},
- 0xab96: []int32{5062},
- 0xab97: []int32{5063},
- 0xab98: []int32{5064},
- 0xab99: []int32{5065},
- 0xab9a: []int32{5066},
- 0xab9b: []int32{5067},
- 0xab9c: []int32{5068},
- 0xab9d: []int32{5069},
- 0xab9e: []int32{5070},
- 0xab9f: []int32{5071},
- 0xaba0: []int32{5072},
- 0xaba1: []int32{5073},
- 0xaba2: []int32{5074},
- 0xaba3: []int32{5075},
- 0xaba4: []int32{5076},
- 0xaba5: []int32{5077},
- 0xaba6: []int32{5078},
- 0xaba7: []int32{5079},
- 0xaba8: []int32{5080},
- 0xaba9: []int32{5081},
- 0xabaa: []int32{5082},
- 0xabab: []int32{5083},
- 0xabac: []int32{5084},
- 0xabad: []int32{5085},
- 0xabae: []int32{5086},
- 0xabaf: []int32{5087},
- 0xabb0: []int32{5088},
- 0xabb1: []int32{5089},
- 0xabb2: []int32{5090},
- 0xabb3: []int32{5091},
- 0xabb4: []int32{5092},
- 0xabb5: []int32{5093},
- 0xabb6: []int32{5094},
- 0xabb7: []int32{5095},
- 0xabb8: []int32{5096},
- 0xabb9: []int32{5097},
- 0xabba: []int32{5098},
- 0xabbb: []int32{5099},
- 0xabbc: []int32{5100},
- 0xabbd: []int32{5101},
- 0xabbe: []int32{5102},
- 0xabbf: []int32{5103},
- 0xfb00: []int32{102, 102},
- 0xfb01: []int32{102, 105},
- 0xfb02: []int32{102, 108},
- 0xfb03: []int32{102, 102, 105},
- 0xfb04: []int32{102, 102, 108},
- 0xfb05: []int32{115, 116},
- 0xfb06: []int32{115, 116},
- 0xfb13: []int32{1396, 1398},
- 0xfb14: []int32{1396, 1381},
- 0xfb15: []int32{1396, 1387},
- 0xfb16: []int32{1406, 1398},
- 0xfb17: []int32{1396, 1389},
- 0xff21: []int32{65345},
- 0xff22: []int32{65346},
- 0xff23: []int32{65347},
- 0xff24: []int32{65348},
- 0xff25: []int32{65349},
- 0xff26: []int32{65350},
- 0xff27: []int32{65351},
- 0xff28: []int32{65352},
- 0xff29: []int32{65353},
- 0xff2a: []int32{65354},
- 0xff2b: []int32{65355},
- 0xff2c: []int32{65356},
- 0xff2d: []int32{65357},
- 0xff2e: []int32{65358},
- 0xff2f: []int32{65359},
- 0xff30: []int32{65360},
- 0xff31: []int32{65361},
- 0xff32: []int32{65362},
- 0xff33: []int32{65363},
- 0xff34: []int32{65364},
- 0xff35: []int32{65365},
- 0xff36: []int32{65366},
- 0xff37: []int32{65367},
- 0xff38: []int32{65368},
- 0xff39: []int32{65369},
- 0xff3a: []int32{65370},
- 0x10400: []int32{66600},
- 0x10401: []int32{66601},
- 0x10402: []int32{66602},
- 0x10403: []int32{66603},
- 0x10404: []int32{66604},
- 0x10405: []int32{66605},
- 0x10406: []int32{66606},
- 0x10407: []int32{66607},
- 0x10408: []int32{66608},
- 0x10409: []int32{66609},
- 0x1040a: []int32{66610},
- 0x1040b: []int32{66611},
- 0x1040c: []int32{66612},
- 0x1040d: []int32{66613},
- 0x1040e: []int32{66614},
- 0x1040f: []int32{66615},
- 0x10410: []int32{66616},
- 0x10411: []int32{66617},
- 0x10412: []int32{66618},
- 0x10413: []int32{66619},
- 0x10414: []int32{66620},
- 0x10415: []int32{66621},
- 0x10416: []int32{66622},
- 0x10417: []int32{66623},
- 0x10418: []int32{66624},
- 0x10419: []int32{66625},
- 0x1041a: []int32{66626},
- 0x1041b: []int32{66627},
- 0x1041c: []int32{66628},
- 0x1041d: []int32{66629},
- 0x1041e: []int32{66630},
- 0x1041f: []int32{66631},
- 0x10420: []int32{66632},
- 0x10421: []int32{66633},
- 0x10422: []int32{66634},
- 0x10423: []int32{66635},
- 0x10424: []int32{66636},
- 0x10425: []int32{66637},
- 0x10426: []int32{66638},
- 0x10427: []int32{66639},
- 0x104b0: []int32{66776},
- 0x104b1: []int32{66777},
- 0x104b2: []int32{66778},
- 0x104b3: []int32{66779},
- 0x104b4: []int32{66780},
- 0x104b5: []int32{66781},
- 0x104b6: []int32{66782},
- 0x104b7: []int32{66783},
- 0x104b8: []int32{66784},
- 0x104b9: []int32{66785},
- 0x104ba: []int32{66786},
- 0x104bb: []int32{66787},
- 0x104bc: []int32{66788},
- 0x104bd: []int32{66789},
- 0x104be: []int32{66790},
- 0x104bf: []int32{66791},
- 0x104c0: []int32{66792},
- 0x104c1: []int32{66793},
- 0x104c2: []int32{66794},
- 0x104c3: []int32{66795},
- 0x104c4: []int32{66796},
- 0x104c5: []int32{66797},
- 0x104c6: []int32{66798},
- 0x104c7: []int32{66799},
- 0x104c8: []int32{66800},
- 0x104c9: []int32{66801},
- 0x104ca: []int32{66802},
- 0x104cb: []int32{66803},
- 0x104cc: []int32{66804},
- 0x104cd: []int32{66805},
- 0x104ce: []int32{66806},
- 0x104cf: []int32{66807},
- 0x104d0: []int32{66808},
- 0x104d1: []int32{66809},
- 0x104d2: []int32{66810},
- 0x104d3: []int32{66811},
- 0x10c80: []int32{68800},
- 0x10c81: []int32{68801},
- 0x10c82: []int32{68802},
- 0x10c83: []int32{68803},
- 0x10c84: []int32{68804},
- 0x10c85: []int32{68805},
- 0x10c86: []int32{68806},
- 0x10c87: []int32{68807},
- 0x10c88: []int32{68808},
- 0x10c89: []int32{68809},
- 0x10c8a: []int32{68810},
- 0x10c8b: []int32{68811},
- 0x10c8c: []int32{68812},
- 0x10c8d: []int32{68813},
- 0x10c8e: []int32{68814},
- 0x10c8f: []int32{68815},
- 0x10c90: []int32{68816},
- 0x10c91: []int32{68817},
- 0x10c92: []int32{68818},
- 0x10c93: []int32{68819},
- 0x10c94: []int32{68820},
- 0x10c95: []int32{68821},
- 0x10c96: []int32{68822},
- 0x10c97: []int32{68823},
- 0x10c98: []int32{68824},
- 0x10c99: []int32{68825},
- 0x10c9a: []int32{68826},
- 0x10c9b: []int32{68827},
- 0x10c9c: []int32{68828},
- 0x10c9d: []int32{68829},
- 0x10c9e: []int32{68830},
- 0x10c9f: []int32{68831},
- 0x10ca0: []int32{68832},
- 0x10ca1: []int32{68833},
- 0x10ca2: []int32{68834},
- 0x10ca3: []int32{68835},
- 0x10ca4: []int32{68836},
- 0x10ca5: []int32{68837},
- 0x10ca6: []int32{68838},
- 0x10ca7: []int32{68839},
- 0x10ca8: []int32{68840},
- 0x10ca9: []int32{68841},
- 0x10caa: []int32{68842},
- 0x10cab: []int32{68843},
- 0x10cac: []int32{68844},
- 0x10cad: []int32{68845},
- 0x10cae: []int32{68846},
- 0x10caf: []int32{68847},
- 0x10cb0: []int32{68848},
- 0x10cb1: []int32{68849},
- 0x10cb2: []int32{68850},
- 0x118a0: []int32{71872},
- 0x118a1: []int32{71873},
- 0x118a2: []int32{71874},
- 0x118a3: []int32{71875},
- 0x118a4: []int32{71876},
- 0x118a5: []int32{71877},
- 0x118a6: []int32{71878},
- 0x118a7: []int32{71879},
- 0x118a8: []int32{71880},
- 0x118a9: []int32{71881},
- 0x118aa: []int32{71882},
- 0x118ab: []int32{71883},
- 0x118ac: []int32{71884},
- 0x118ad: []int32{71885},
- 0x118ae: []int32{71886},
- 0x118af: []int32{71887},
- 0x118b0: []int32{71888},
- 0x118b1: []int32{71889},
- 0x118b2: []int32{71890},
- 0x118b3: []int32{71891},
- 0x118b4: []int32{71892},
- 0x118b5: []int32{71893},
- 0x118b6: []int32{71894},
- 0x118b7: []int32{71895},
- 0x118b8: []int32{71896},
- 0x118b9: []int32{71897},
- 0x118ba: []int32{71898},
- 0x118bb: []int32{71899},
- 0x118bc: []int32{71900},
- 0x118bd: []int32{71901},
- 0x118be: []int32{71902},
- 0x118bf: []int32{71903},
- 0x16e40: []int32{93792},
- 0x16e41: []int32{93793},
- 0x16e42: []int32{93794},
- 0x16e43: []int32{93795},
- 0x16e44: []int32{93796},
- 0x16e45: []int32{93797},
- 0x16e46: []int32{93798},
- 0x16e47: []int32{93799},
- 0x16e48: []int32{93800},
- 0x16e49: []int32{93801},
- 0x16e4a: []int32{93802},
- 0x16e4b: []int32{93803},
- 0x16e4c: []int32{93804},
- 0x16e4d: []int32{93805},
- 0x16e4e: []int32{93806},
- 0x16e4f: []int32{93807},
- 0x16e50: []int32{93808},
- 0x16e51: []int32{93809},
- 0x16e52: []int32{93810},
- 0x16e53: []int32{93811},
- 0x16e54: []int32{93812},
- 0x16e55: []int32{93813},
- 0x16e56: []int32{93814},
- 0x16e57: []int32{93815},
- 0x16e58: []int32{93816},
- 0x16e59: []int32{93817},
- 0x16e5a: []int32{93818},
- 0x16e5b: []int32{93819},
- 0x16e5c: []int32{93820},
- 0x16e5d: []int32{93821},
- 0x16e5e: []int32{93822},
- 0x16e5f: []int32{93823},
- 0x1e900: []int32{125218},
- 0x1e901: []int32{125219},
- 0x1e902: []int32{125220},
- 0x1e903: []int32{125221},
- 0x1e904: []int32{125222},
- 0x1e905: []int32{125223},
- 0x1e906: []int32{125224},
- 0x1e907: []int32{125225},
- 0x1e908: []int32{125226},
- 0x1e909: []int32{125227},
- 0x1e90a: []int32{125228},
- 0x1e90b: []int32{125229},
- 0x1e90c: []int32{125230},
- 0x1e90d: []int32{125231},
- 0x1e90e: []int32{125232},
- 0x1e90f: []int32{125233},
- 0x1e910: []int32{125234},
- 0x1e911: []int32{125235},
- 0x1e912: []int32{125236},
- 0x1e913: []int32{125237},
- 0x1e914: []int32{125238},
- 0x1e915: []int32{125239},
- 0x1e916: []int32{125240},
- 0x1e917: []int32{125241},
- 0x1e918: []int32{125242},
- 0x1e919: []int32{125243},
- 0x1e91a: []int32{125244},
- 0x1e91b: []int32{125245},
- 0x1e91c: []int32{125246},
- 0x1e91d: []int32{125247},
- 0x1e91e: []int32{125248},
- 0x1e91f: []int32{125249},
- 0x1e920: []int32{125250},
- 0x1e921: []int32{125251},
+var unicodeCaseFoldings = map[rune][]rune {
+ 0x41 : []int32{97},
+ 0x42 : []int32{98},
+ 0x43 : []int32{99},
+ 0x44 : []int32{100},
+ 0x45 : []int32{101},
+ 0x46 : []int32{102},
+ 0x47 : []int32{103},
+ 0x48 : []int32{104},
+ 0x49 : []int32{105},
+ 0x4a : []int32{106},
+ 0x4b : []int32{107},
+ 0x4c : []int32{108},
+ 0x4d : []int32{109},
+ 0x4e : []int32{110},
+ 0x4f : []int32{111},
+ 0x50 : []int32{112},
+ 0x51 : []int32{113},
+ 0x52 : []int32{114},
+ 0x53 : []int32{115},
+ 0x54 : []int32{116},
+ 0x55 : []int32{117},
+ 0x56 : []int32{118},
+ 0x57 : []int32{119},
+ 0x58 : []int32{120},
+ 0x59 : []int32{121},
+ 0x5a : []int32{122},
+ 0xb5 : []int32{956},
+ 0xc0 : []int32{224},
+ 0xc1 : []int32{225},
+ 0xc2 : []int32{226},
+ 0xc3 : []int32{227},
+ 0xc4 : []int32{228},
+ 0xc5 : []int32{229},
+ 0xc6 : []int32{230},
+ 0xc7 : []int32{231},
+ 0xc8 : []int32{232},
+ 0xc9 : []int32{233},
+ 0xca : []int32{234},
+ 0xcb : []int32{235},
+ 0xcc : []int32{236},
+ 0xcd : []int32{237},
+ 0xce : []int32{238},
+ 0xcf : []int32{239},
+ 0xd0 : []int32{240},
+ 0xd1 : []int32{241},
+ 0xd2 : []int32{242},
+ 0xd3 : []int32{243},
+ 0xd4 : []int32{244},
+ 0xd5 : []int32{245},
+ 0xd6 : []int32{246},
+ 0xd8 : []int32{248},
+ 0xd9 : []int32{249},
+ 0xda : []int32{250},
+ 0xdb : []int32{251},
+ 0xdc : []int32{252},
+ 0xdd : []int32{253},
+ 0xde : []int32{254},
+ 0xdf : []int32{115, 115},
+ 0x100 : []int32{257},
+ 0x102 : []int32{259},
+ 0x104 : []int32{261},
+ 0x106 : []int32{263},
+ 0x108 : []int32{265},
+ 0x10a : []int32{267},
+ 0x10c : []int32{269},
+ 0x10e : []int32{271},
+ 0x110 : []int32{273},
+ 0x112 : []int32{275},
+ 0x114 : []int32{277},
+ 0x116 : []int32{279},
+ 0x118 : []int32{281},
+ 0x11a : []int32{283},
+ 0x11c : []int32{285},
+ 0x11e : []int32{287},
+ 0x120 : []int32{289},
+ 0x122 : []int32{291},
+ 0x124 : []int32{293},
+ 0x126 : []int32{295},
+ 0x128 : []int32{297},
+ 0x12a : []int32{299},
+ 0x12c : []int32{301},
+ 0x12e : []int32{303},
+ 0x130 : []int32{105, 775},
+ 0x132 : []int32{307},
+ 0x134 : []int32{309},
+ 0x136 : []int32{311},
+ 0x139 : []int32{314},
+ 0x13b : []int32{316},
+ 0x13d : []int32{318},
+ 0x13f : []int32{320},
+ 0x141 : []int32{322},
+ 0x143 : []int32{324},
+ 0x145 : []int32{326},
+ 0x147 : []int32{328},
+ 0x149 : []int32{700, 110},
+ 0x14a : []int32{331},
+ 0x14c : []int32{333},
+ 0x14e : []int32{335},
+ 0x150 : []int32{337},
+ 0x152 : []int32{339},
+ 0x154 : []int32{341},
+ 0x156 : []int32{343},
+ 0x158 : []int32{345},
+ 0x15a : []int32{347},
+ 0x15c : []int32{349},
+ 0x15e : []int32{351},
+ 0x160 : []int32{353},
+ 0x162 : []int32{355},
+ 0x164 : []int32{357},
+ 0x166 : []int32{359},
+ 0x168 : []int32{361},
+ 0x16a : []int32{363},
+ 0x16c : []int32{365},
+ 0x16e : []int32{367},
+ 0x170 : []int32{369},
+ 0x172 : []int32{371},
+ 0x174 : []int32{373},
+ 0x176 : []int32{375},
+ 0x178 : []int32{255},
+ 0x179 : []int32{378},
+ 0x17b : []int32{380},
+ 0x17d : []int32{382},
+ 0x17f : []int32{115},
+ 0x181 : []int32{595},
+ 0x182 : []int32{387},
+ 0x184 : []int32{389},
+ 0x186 : []int32{596},
+ 0x187 : []int32{392},
+ 0x189 : []int32{598},
+ 0x18a : []int32{599},
+ 0x18b : []int32{396},
+ 0x18e : []int32{477},
+ 0x18f : []int32{601},
+ 0x190 : []int32{603},
+ 0x191 : []int32{402},
+ 0x193 : []int32{608},
+ 0x194 : []int32{611},
+ 0x196 : []int32{617},
+ 0x197 : []int32{616},
+ 0x198 : []int32{409},
+ 0x19c : []int32{623},
+ 0x19d : []int32{626},
+ 0x19f : []int32{629},
+ 0x1a0 : []int32{417},
+ 0x1a2 : []int32{419},
+ 0x1a4 : []int32{421},
+ 0x1a6 : []int32{640},
+ 0x1a7 : []int32{424},
+ 0x1a9 : []int32{643},
+ 0x1ac : []int32{429},
+ 0x1ae : []int32{648},
+ 0x1af : []int32{432},
+ 0x1b1 : []int32{650},
+ 0x1b2 : []int32{651},
+ 0x1b3 : []int32{436},
+ 0x1b5 : []int32{438},
+ 0x1b7 : []int32{658},
+ 0x1b8 : []int32{441},
+ 0x1bc : []int32{445},
+ 0x1c4 : []int32{454},
+ 0x1c5 : []int32{454},
+ 0x1c7 : []int32{457},
+ 0x1c8 : []int32{457},
+ 0x1ca : []int32{460},
+ 0x1cb : []int32{460},
+ 0x1cd : []int32{462},
+ 0x1cf : []int32{464},
+ 0x1d1 : []int32{466},
+ 0x1d3 : []int32{468},
+ 0x1d5 : []int32{470},
+ 0x1d7 : []int32{472},
+ 0x1d9 : []int32{474},
+ 0x1db : []int32{476},
+ 0x1de : []int32{479},
+ 0x1e0 : []int32{481},
+ 0x1e2 : []int32{483},
+ 0x1e4 : []int32{485},
+ 0x1e6 : []int32{487},
+ 0x1e8 : []int32{489},
+ 0x1ea : []int32{491},
+ 0x1ec : []int32{493},
+ 0x1ee : []int32{495},
+ 0x1f0 : []int32{106, 780},
+ 0x1f1 : []int32{499},
+ 0x1f2 : []int32{499},
+ 0x1f4 : []int32{501},
+ 0x1f6 : []int32{405},
+ 0x1f7 : []int32{447},
+ 0x1f8 : []int32{505},
+ 0x1fa : []int32{507},
+ 0x1fc : []int32{509},
+ 0x1fe : []int32{511},
+ 0x200 : []int32{513},
+ 0x202 : []int32{515},
+ 0x204 : []int32{517},
+ 0x206 : []int32{519},
+ 0x208 : []int32{521},
+ 0x20a : []int32{523},
+ 0x20c : []int32{525},
+ 0x20e : []int32{527},
+ 0x210 : []int32{529},
+ 0x212 : []int32{531},
+ 0x214 : []int32{533},
+ 0x216 : []int32{535},
+ 0x218 : []int32{537},
+ 0x21a : []int32{539},
+ 0x21c : []int32{541},
+ 0x21e : []int32{543},
+ 0x220 : []int32{414},
+ 0x222 : []int32{547},
+ 0x224 : []int32{549},
+ 0x226 : []int32{551},
+ 0x228 : []int32{553},
+ 0x22a : []int32{555},
+ 0x22c : []int32{557},
+ 0x22e : []int32{559},
+ 0x230 : []int32{561},
+ 0x232 : []int32{563},
+ 0x23a : []int32{11365},
+ 0x23b : []int32{572},
+ 0x23d : []int32{410},
+ 0x23e : []int32{11366},
+ 0x241 : []int32{578},
+ 0x243 : []int32{384},
+ 0x244 : []int32{649},
+ 0x245 : []int32{652},
+ 0x246 : []int32{583},
+ 0x248 : []int32{585},
+ 0x24a : []int32{587},
+ 0x24c : []int32{589},
+ 0x24e : []int32{591},
+ 0x345 : []int32{953},
+ 0x370 : []int32{881},
+ 0x372 : []int32{883},
+ 0x376 : []int32{887},
+ 0x37f : []int32{1011},
+ 0x386 : []int32{940},
+ 0x388 : []int32{941},
+ 0x389 : []int32{942},
+ 0x38a : []int32{943},
+ 0x38c : []int32{972},
+ 0x38e : []int32{973},
+ 0x38f : []int32{974},
+ 0x390 : []int32{953, 776, 769},
+ 0x391 : []int32{945},
+ 0x392 : []int32{946},
+ 0x393 : []int32{947},
+ 0x394 : []int32{948},
+ 0x395 : []int32{949},
+ 0x396 : []int32{950},
+ 0x397 : []int32{951},
+ 0x398 : []int32{952},
+ 0x399 : []int32{953},
+ 0x39a : []int32{954},
+ 0x39b : []int32{955},
+ 0x39c : []int32{956},
+ 0x39d : []int32{957},
+ 0x39e : []int32{958},
+ 0x39f : []int32{959},
+ 0x3a0 : []int32{960},
+ 0x3a1 : []int32{961},
+ 0x3a3 : []int32{963},
+ 0x3a4 : []int32{964},
+ 0x3a5 : []int32{965},
+ 0x3a6 : []int32{966},
+ 0x3a7 : []int32{967},
+ 0x3a8 : []int32{968},
+ 0x3a9 : []int32{969},
+ 0x3aa : []int32{970},
+ 0x3ab : []int32{971},
+ 0x3b0 : []int32{965, 776, 769},
+ 0x3c2 : []int32{963},
+ 0x3cf : []int32{983},
+ 0x3d0 : []int32{946},
+ 0x3d1 : []int32{952},
+ 0x3d5 : []int32{966},
+ 0x3d6 : []int32{960},
+ 0x3d8 : []int32{985},
+ 0x3da : []int32{987},
+ 0x3dc : []int32{989},
+ 0x3de : []int32{991},
+ 0x3e0 : []int32{993},
+ 0x3e2 : []int32{995},
+ 0x3e4 : []int32{997},
+ 0x3e6 : []int32{999},
+ 0x3e8 : []int32{1001},
+ 0x3ea : []int32{1003},
+ 0x3ec : []int32{1005},
+ 0x3ee : []int32{1007},
+ 0x3f0 : []int32{954},
+ 0x3f1 : []int32{961},
+ 0x3f4 : []int32{952},
+ 0x3f5 : []int32{949},
+ 0x3f7 : []int32{1016},
+ 0x3f9 : []int32{1010},
+ 0x3fa : []int32{1019},
+ 0x3fd : []int32{891},
+ 0x3fe : []int32{892},
+ 0x3ff : []int32{893},
+ 0x400 : []int32{1104},
+ 0x401 : []int32{1105},
+ 0x402 : []int32{1106},
+ 0x403 : []int32{1107},
+ 0x404 : []int32{1108},
+ 0x405 : []int32{1109},
+ 0x406 : []int32{1110},
+ 0x407 : []int32{1111},
+ 0x408 : []int32{1112},
+ 0x409 : []int32{1113},
+ 0x40a : []int32{1114},
+ 0x40b : []int32{1115},
+ 0x40c : []int32{1116},
+ 0x40d : []int32{1117},
+ 0x40e : []int32{1118},
+ 0x40f : []int32{1119},
+ 0x410 : []int32{1072},
+ 0x411 : []int32{1073},
+ 0x412 : []int32{1074},
+ 0x413 : []int32{1075},
+ 0x414 : []int32{1076},
+ 0x415 : []int32{1077},
+ 0x416 : []int32{1078},
+ 0x417 : []int32{1079},
+ 0x418 : []int32{1080},
+ 0x419 : []int32{1081},
+ 0x41a : []int32{1082},
+ 0x41b : []int32{1083},
+ 0x41c : []int32{1084},
+ 0x41d : []int32{1085},
+ 0x41e : []int32{1086},
+ 0x41f : []int32{1087},
+ 0x420 : []int32{1088},
+ 0x421 : []int32{1089},
+ 0x422 : []int32{1090},
+ 0x423 : []int32{1091},
+ 0x424 : []int32{1092},
+ 0x425 : []int32{1093},
+ 0x426 : []int32{1094},
+ 0x427 : []int32{1095},
+ 0x428 : []int32{1096},
+ 0x429 : []int32{1097},
+ 0x42a : []int32{1098},
+ 0x42b : []int32{1099},
+ 0x42c : []int32{1100},
+ 0x42d : []int32{1101},
+ 0x42e : []int32{1102},
+ 0x42f : []int32{1103},
+ 0x460 : []int32{1121},
+ 0x462 : []int32{1123},
+ 0x464 : []int32{1125},
+ 0x466 : []int32{1127},
+ 0x468 : []int32{1129},
+ 0x46a : []int32{1131},
+ 0x46c : []int32{1133},
+ 0x46e : []int32{1135},
+ 0x470 : []int32{1137},
+ 0x472 : []int32{1139},
+ 0x474 : []int32{1141},
+ 0x476 : []int32{1143},
+ 0x478 : []int32{1145},
+ 0x47a : []int32{1147},
+ 0x47c : []int32{1149},
+ 0x47e : []int32{1151},
+ 0x480 : []int32{1153},
+ 0x48a : []int32{1163},
+ 0x48c : []int32{1165},
+ 0x48e : []int32{1167},
+ 0x490 : []int32{1169},
+ 0x492 : []int32{1171},
+ 0x494 : []int32{1173},
+ 0x496 : []int32{1175},
+ 0x498 : []int32{1177},
+ 0x49a : []int32{1179},
+ 0x49c : []int32{1181},
+ 0x49e : []int32{1183},
+ 0x4a0 : []int32{1185},
+ 0x4a2 : []int32{1187},
+ 0x4a4 : []int32{1189},
+ 0x4a6 : []int32{1191},
+ 0x4a8 : []int32{1193},
+ 0x4aa : []int32{1195},
+ 0x4ac : []int32{1197},
+ 0x4ae : []int32{1199},
+ 0x4b0 : []int32{1201},
+ 0x4b2 : []int32{1203},
+ 0x4b4 : []int32{1205},
+ 0x4b6 : []int32{1207},
+ 0x4b8 : []int32{1209},
+ 0x4ba : []int32{1211},
+ 0x4bc : []int32{1213},
+ 0x4be : []int32{1215},
+ 0x4c0 : []int32{1231},
+ 0x4c1 : []int32{1218},
+ 0x4c3 : []int32{1220},
+ 0x4c5 : []int32{1222},
+ 0x4c7 : []int32{1224},
+ 0x4c9 : []int32{1226},
+ 0x4cb : []int32{1228},
+ 0x4cd : []int32{1230},
+ 0x4d0 : []int32{1233},
+ 0x4d2 : []int32{1235},
+ 0x4d4 : []int32{1237},
+ 0x4d6 : []int32{1239},
+ 0x4d8 : []int32{1241},
+ 0x4da : []int32{1243},
+ 0x4dc : []int32{1245},
+ 0x4de : []int32{1247},
+ 0x4e0 : []int32{1249},
+ 0x4e2 : []int32{1251},
+ 0x4e4 : []int32{1253},
+ 0x4e6 : []int32{1255},
+ 0x4e8 : []int32{1257},
+ 0x4ea : []int32{1259},
+ 0x4ec : []int32{1261},
+ 0x4ee : []int32{1263},
+ 0x4f0 : []int32{1265},
+ 0x4f2 : []int32{1267},
+ 0x4f4 : []int32{1269},
+ 0x4f6 : []int32{1271},
+ 0x4f8 : []int32{1273},
+ 0x4fa : []int32{1275},
+ 0x4fc : []int32{1277},
+ 0x4fe : []int32{1279},
+ 0x500 : []int32{1281},
+ 0x502 : []int32{1283},
+ 0x504 : []int32{1285},
+ 0x506 : []int32{1287},
+ 0x508 : []int32{1289},
+ 0x50a : []int32{1291},
+ 0x50c : []int32{1293},
+ 0x50e : []int32{1295},
+ 0x510 : []int32{1297},
+ 0x512 : []int32{1299},
+ 0x514 : []int32{1301},
+ 0x516 : []int32{1303},
+ 0x518 : []int32{1305},
+ 0x51a : []int32{1307},
+ 0x51c : []int32{1309},
+ 0x51e : []int32{1311},
+ 0x520 : []int32{1313},
+ 0x522 : []int32{1315},
+ 0x524 : []int32{1317},
+ 0x526 : []int32{1319},
+ 0x528 : []int32{1321},
+ 0x52a : []int32{1323},
+ 0x52c : []int32{1325},
+ 0x52e : []int32{1327},
+ 0x531 : []int32{1377},
+ 0x532 : []int32{1378},
+ 0x533 : []int32{1379},
+ 0x534 : []int32{1380},
+ 0x535 : []int32{1381},
+ 0x536 : []int32{1382},
+ 0x537 : []int32{1383},
+ 0x538 : []int32{1384},
+ 0x539 : []int32{1385},
+ 0x53a : []int32{1386},
+ 0x53b : []int32{1387},
+ 0x53c : []int32{1388},
+ 0x53d : []int32{1389},
+ 0x53e : []int32{1390},
+ 0x53f : []int32{1391},
+ 0x540 : []int32{1392},
+ 0x541 : []int32{1393},
+ 0x542 : []int32{1394},
+ 0x543 : []int32{1395},
+ 0x544 : []int32{1396},
+ 0x545 : []int32{1397},
+ 0x546 : []int32{1398},
+ 0x547 : []int32{1399},
+ 0x548 : []int32{1400},
+ 0x549 : []int32{1401},
+ 0x54a : []int32{1402},
+ 0x54b : []int32{1403},
+ 0x54c : []int32{1404},
+ 0x54d : []int32{1405},
+ 0x54e : []int32{1406},
+ 0x54f : []int32{1407},
+ 0x550 : []int32{1408},
+ 0x551 : []int32{1409},
+ 0x552 : []int32{1410},
+ 0x553 : []int32{1411},
+ 0x554 : []int32{1412},
+ 0x555 : []int32{1413},
+ 0x556 : []int32{1414},
+ 0x587 : []int32{1381, 1410},
+ 0x10a0 : []int32{11520},
+ 0x10a1 : []int32{11521},
+ 0x10a2 : []int32{11522},
+ 0x10a3 : []int32{11523},
+ 0x10a4 : []int32{11524},
+ 0x10a5 : []int32{11525},
+ 0x10a6 : []int32{11526},
+ 0x10a7 : []int32{11527},
+ 0x10a8 : []int32{11528},
+ 0x10a9 : []int32{11529},
+ 0x10aa : []int32{11530},
+ 0x10ab : []int32{11531},
+ 0x10ac : []int32{11532},
+ 0x10ad : []int32{11533},
+ 0x10ae : []int32{11534},
+ 0x10af : []int32{11535},
+ 0x10b0 : []int32{11536},
+ 0x10b1 : []int32{11537},
+ 0x10b2 : []int32{11538},
+ 0x10b3 : []int32{11539},
+ 0x10b4 : []int32{11540},
+ 0x10b5 : []int32{11541},
+ 0x10b6 : []int32{11542},
+ 0x10b7 : []int32{11543},
+ 0x10b8 : []int32{11544},
+ 0x10b9 : []int32{11545},
+ 0x10ba : []int32{11546},
+ 0x10bb : []int32{11547},
+ 0x10bc : []int32{11548},
+ 0x10bd : []int32{11549},
+ 0x10be : []int32{11550},
+ 0x10bf : []int32{11551},
+ 0x10c0 : []int32{11552},
+ 0x10c1 : []int32{11553},
+ 0x10c2 : []int32{11554},
+ 0x10c3 : []int32{11555},
+ 0x10c4 : []int32{11556},
+ 0x10c5 : []int32{11557},
+ 0x10c7 : []int32{11559},
+ 0x10cd : []int32{11565},
+ 0x13f8 : []int32{5104},
+ 0x13f9 : []int32{5105},
+ 0x13fa : []int32{5106},
+ 0x13fb : []int32{5107},
+ 0x13fc : []int32{5108},
+ 0x13fd : []int32{5109},
+ 0x1c80 : []int32{1074},
+ 0x1c81 : []int32{1076},
+ 0x1c82 : []int32{1086},
+ 0x1c83 : []int32{1089},
+ 0x1c84 : []int32{1090},
+ 0x1c85 : []int32{1090},
+ 0x1c86 : []int32{1098},
+ 0x1c87 : []int32{1123},
+ 0x1c88 : []int32{42571},
+ 0x1c90 : []int32{4304},
+ 0x1c91 : []int32{4305},
+ 0x1c92 : []int32{4306},
+ 0x1c93 : []int32{4307},
+ 0x1c94 : []int32{4308},
+ 0x1c95 : []int32{4309},
+ 0x1c96 : []int32{4310},
+ 0x1c97 : []int32{4311},
+ 0x1c98 : []int32{4312},
+ 0x1c99 : []int32{4313},
+ 0x1c9a : []int32{4314},
+ 0x1c9b : []int32{4315},
+ 0x1c9c : []int32{4316},
+ 0x1c9d : []int32{4317},
+ 0x1c9e : []int32{4318},
+ 0x1c9f : []int32{4319},
+ 0x1ca0 : []int32{4320},
+ 0x1ca1 : []int32{4321},
+ 0x1ca2 : []int32{4322},
+ 0x1ca3 : []int32{4323},
+ 0x1ca4 : []int32{4324},
+ 0x1ca5 : []int32{4325},
+ 0x1ca6 : []int32{4326},
+ 0x1ca7 : []int32{4327},
+ 0x1ca8 : []int32{4328},
+ 0x1ca9 : []int32{4329},
+ 0x1caa : []int32{4330},
+ 0x1cab : []int32{4331},
+ 0x1cac : []int32{4332},
+ 0x1cad : []int32{4333},
+ 0x1cae : []int32{4334},
+ 0x1caf : []int32{4335},
+ 0x1cb0 : []int32{4336},
+ 0x1cb1 : []int32{4337},
+ 0x1cb2 : []int32{4338},
+ 0x1cb3 : []int32{4339},
+ 0x1cb4 : []int32{4340},
+ 0x1cb5 : []int32{4341},
+ 0x1cb6 : []int32{4342},
+ 0x1cb7 : []int32{4343},
+ 0x1cb8 : []int32{4344},
+ 0x1cb9 : []int32{4345},
+ 0x1cba : []int32{4346},
+ 0x1cbd : []int32{4349},
+ 0x1cbe : []int32{4350},
+ 0x1cbf : []int32{4351},
+ 0x1e00 : []int32{7681},
+ 0x1e02 : []int32{7683},
+ 0x1e04 : []int32{7685},
+ 0x1e06 : []int32{7687},
+ 0x1e08 : []int32{7689},
+ 0x1e0a : []int32{7691},
+ 0x1e0c : []int32{7693},
+ 0x1e0e : []int32{7695},
+ 0x1e10 : []int32{7697},
+ 0x1e12 : []int32{7699},
+ 0x1e14 : []int32{7701},
+ 0x1e16 : []int32{7703},
+ 0x1e18 : []int32{7705},
+ 0x1e1a : []int32{7707},
+ 0x1e1c : []int32{7709},
+ 0x1e1e : []int32{7711},
+ 0x1e20 : []int32{7713},
+ 0x1e22 : []int32{7715},
+ 0x1e24 : []int32{7717},
+ 0x1e26 : []int32{7719},
+ 0x1e28 : []int32{7721},
+ 0x1e2a : []int32{7723},
+ 0x1e2c : []int32{7725},
+ 0x1e2e : []int32{7727},
+ 0x1e30 : []int32{7729},
+ 0x1e32 : []int32{7731},
+ 0x1e34 : []int32{7733},
+ 0x1e36 : []int32{7735},
+ 0x1e38 : []int32{7737},
+ 0x1e3a : []int32{7739},
+ 0x1e3c : []int32{7741},
+ 0x1e3e : []int32{7743},
+ 0x1e40 : []int32{7745},
+ 0x1e42 : []int32{7747},
+ 0x1e44 : []int32{7749},
+ 0x1e46 : []int32{7751},
+ 0x1e48 : []int32{7753},
+ 0x1e4a : []int32{7755},
+ 0x1e4c : []int32{7757},
+ 0x1e4e : []int32{7759},
+ 0x1e50 : []int32{7761},
+ 0x1e52 : []int32{7763},
+ 0x1e54 : []int32{7765},
+ 0x1e56 : []int32{7767},
+ 0x1e58 : []int32{7769},
+ 0x1e5a : []int32{7771},
+ 0x1e5c : []int32{7773},
+ 0x1e5e : []int32{7775},
+ 0x1e60 : []int32{7777},
+ 0x1e62 : []int32{7779},
+ 0x1e64 : []int32{7781},
+ 0x1e66 : []int32{7783},
+ 0x1e68 : []int32{7785},
+ 0x1e6a : []int32{7787},
+ 0x1e6c : []int32{7789},
+ 0x1e6e : []int32{7791},
+ 0x1e70 : []int32{7793},
+ 0x1e72 : []int32{7795},
+ 0x1e74 : []int32{7797},
+ 0x1e76 : []int32{7799},
+ 0x1e78 : []int32{7801},
+ 0x1e7a : []int32{7803},
+ 0x1e7c : []int32{7805},
+ 0x1e7e : []int32{7807},
+ 0x1e80 : []int32{7809},
+ 0x1e82 : []int32{7811},
+ 0x1e84 : []int32{7813},
+ 0x1e86 : []int32{7815},
+ 0x1e88 : []int32{7817},
+ 0x1e8a : []int32{7819},
+ 0x1e8c : []int32{7821},
+ 0x1e8e : []int32{7823},
+ 0x1e90 : []int32{7825},
+ 0x1e92 : []int32{7827},
+ 0x1e94 : []int32{7829},
+ 0x1e96 : []int32{104, 817},
+ 0x1e97 : []int32{116, 776},
+ 0x1e98 : []int32{119, 778},
+ 0x1e99 : []int32{121, 778},
+ 0x1e9a : []int32{97, 702},
+ 0x1e9b : []int32{7777},
+ 0x1e9e : []int32{115, 115},
+ 0x1ea0 : []int32{7841},
+ 0x1ea2 : []int32{7843},
+ 0x1ea4 : []int32{7845},
+ 0x1ea6 : []int32{7847},
+ 0x1ea8 : []int32{7849},
+ 0x1eaa : []int32{7851},
+ 0x1eac : []int32{7853},
+ 0x1eae : []int32{7855},
+ 0x1eb0 : []int32{7857},
+ 0x1eb2 : []int32{7859},
+ 0x1eb4 : []int32{7861},
+ 0x1eb6 : []int32{7863},
+ 0x1eb8 : []int32{7865},
+ 0x1eba : []int32{7867},
+ 0x1ebc : []int32{7869},
+ 0x1ebe : []int32{7871},
+ 0x1ec0 : []int32{7873},
+ 0x1ec2 : []int32{7875},
+ 0x1ec4 : []int32{7877},
+ 0x1ec6 : []int32{7879},
+ 0x1ec8 : []int32{7881},
+ 0x1eca : []int32{7883},
+ 0x1ecc : []int32{7885},
+ 0x1ece : []int32{7887},
+ 0x1ed0 : []int32{7889},
+ 0x1ed2 : []int32{7891},
+ 0x1ed4 : []int32{7893},
+ 0x1ed6 : []int32{7895},
+ 0x1ed8 : []int32{7897},
+ 0x1eda : []int32{7899},
+ 0x1edc : []int32{7901},
+ 0x1ede : []int32{7903},
+ 0x1ee0 : []int32{7905},
+ 0x1ee2 : []int32{7907},
+ 0x1ee4 : []int32{7909},
+ 0x1ee6 : []int32{7911},
+ 0x1ee8 : []int32{7913},
+ 0x1eea : []int32{7915},
+ 0x1eec : []int32{7917},
+ 0x1eee : []int32{7919},
+ 0x1ef0 : []int32{7921},
+ 0x1ef2 : []int32{7923},
+ 0x1ef4 : []int32{7925},
+ 0x1ef6 : []int32{7927},
+ 0x1ef8 : []int32{7929},
+ 0x1efa : []int32{7931},
+ 0x1efc : []int32{7933},
+ 0x1efe : []int32{7935},
+ 0x1f08 : []int32{7936},
+ 0x1f09 : []int32{7937},
+ 0x1f0a : []int32{7938},
+ 0x1f0b : []int32{7939},
+ 0x1f0c : []int32{7940},
+ 0x1f0d : []int32{7941},
+ 0x1f0e : []int32{7942},
+ 0x1f0f : []int32{7943},
+ 0x1f18 : []int32{7952},
+ 0x1f19 : []int32{7953},
+ 0x1f1a : []int32{7954},
+ 0x1f1b : []int32{7955},
+ 0x1f1c : []int32{7956},
+ 0x1f1d : []int32{7957},
+ 0x1f28 : []int32{7968},
+ 0x1f29 : []int32{7969},
+ 0x1f2a : []int32{7970},
+ 0x1f2b : []int32{7971},
+ 0x1f2c : []int32{7972},
+ 0x1f2d : []int32{7973},
+ 0x1f2e : []int32{7974},
+ 0x1f2f : []int32{7975},
+ 0x1f38 : []int32{7984},
+ 0x1f39 : []int32{7985},
+ 0x1f3a : []int32{7986},
+ 0x1f3b : []int32{7987},
+ 0x1f3c : []int32{7988},
+ 0x1f3d : []int32{7989},
+ 0x1f3e : []int32{7990},
+ 0x1f3f : []int32{7991},
+ 0x1f48 : []int32{8000},
+ 0x1f49 : []int32{8001},
+ 0x1f4a : []int32{8002},
+ 0x1f4b : []int32{8003},
+ 0x1f4c : []int32{8004},
+ 0x1f4d : []int32{8005},
+ 0x1f50 : []int32{965, 787},
+ 0x1f52 : []int32{965, 787, 768},
+ 0x1f54 : []int32{965, 787, 769},
+ 0x1f56 : []int32{965, 787, 834},
+ 0x1f59 : []int32{8017},
+ 0x1f5b : []int32{8019},
+ 0x1f5d : []int32{8021},
+ 0x1f5f : []int32{8023},
+ 0x1f68 : []int32{8032},
+ 0x1f69 : []int32{8033},
+ 0x1f6a : []int32{8034},
+ 0x1f6b : []int32{8035},
+ 0x1f6c : []int32{8036},
+ 0x1f6d : []int32{8037},
+ 0x1f6e : []int32{8038},
+ 0x1f6f : []int32{8039},
+ 0x1f80 : []int32{7936, 953},
+ 0x1f81 : []int32{7937, 953},
+ 0x1f82 : []int32{7938, 953},
+ 0x1f83 : []int32{7939, 953},
+ 0x1f84 : []int32{7940, 953},
+ 0x1f85 : []int32{7941, 953},
+ 0x1f86 : []int32{7942, 953},
+ 0x1f87 : []int32{7943, 953},
+ 0x1f88 : []int32{7936, 953},
+ 0x1f89 : []int32{7937, 953},
+ 0x1f8a : []int32{7938, 953},
+ 0x1f8b : []int32{7939, 953},
+ 0x1f8c : []int32{7940, 953},
+ 0x1f8d : []int32{7941, 953},
+ 0x1f8e : []int32{7942, 953},
+ 0x1f8f : []int32{7943, 953},
+ 0x1f90 : []int32{7968, 953},
+ 0x1f91 : []int32{7969, 953},
+ 0x1f92 : []int32{7970, 953},
+ 0x1f93 : []int32{7971, 953},
+ 0x1f94 : []int32{7972, 953},
+ 0x1f95 : []int32{7973, 953},
+ 0x1f96 : []int32{7974, 953},
+ 0x1f97 : []int32{7975, 953},
+ 0x1f98 : []int32{7968, 953},
+ 0x1f99 : []int32{7969, 953},
+ 0x1f9a : []int32{7970, 953},
+ 0x1f9b : []int32{7971, 953},
+ 0x1f9c : []int32{7972, 953},
+ 0x1f9d : []int32{7973, 953},
+ 0x1f9e : []int32{7974, 953},
+ 0x1f9f : []int32{7975, 953},
+ 0x1fa0 : []int32{8032, 953},
+ 0x1fa1 : []int32{8033, 953},
+ 0x1fa2 : []int32{8034, 953},
+ 0x1fa3 : []int32{8035, 953},
+ 0x1fa4 : []int32{8036, 953},
+ 0x1fa5 : []int32{8037, 953},
+ 0x1fa6 : []int32{8038, 953},
+ 0x1fa7 : []int32{8039, 953},
+ 0x1fa8 : []int32{8032, 953},
+ 0x1fa9 : []int32{8033, 953},
+ 0x1faa : []int32{8034, 953},
+ 0x1fab : []int32{8035, 953},
+ 0x1fac : []int32{8036, 953},
+ 0x1fad : []int32{8037, 953},
+ 0x1fae : []int32{8038, 953},
+ 0x1faf : []int32{8039, 953},
+ 0x1fb2 : []int32{8048, 953},
+ 0x1fb3 : []int32{945, 953},
+ 0x1fb4 : []int32{940, 953},
+ 0x1fb6 : []int32{945, 834},
+ 0x1fb7 : []int32{945, 834, 953},
+ 0x1fb8 : []int32{8112},
+ 0x1fb9 : []int32{8113},
+ 0x1fba : []int32{8048},
+ 0x1fbb : []int32{8049},
+ 0x1fbc : []int32{945, 953},
+ 0x1fbe : []int32{953},
+ 0x1fc2 : []int32{8052, 953},
+ 0x1fc3 : []int32{951, 953},
+ 0x1fc4 : []int32{942, 953},
+ 0x1fc6 : []int32{951, 834},
+ 0x1fc7 : []int32{951, 834, 953},
+ 0x1fc8 : []int32{8050},
+ 0x1fc9 : []int32{8051},
+ 0x1fca : []int32{8052},
+ 0x1fcb : []int32{8053},
+ 0x1fcc : []int32{951, 953},
+ 0x1fd2 : []int32{953, 776, 768},
+ 0x1fd3 : []int32{953, 776, 769},
+ 0x1fd6 : []int32{953, 834},
+ 0x1fd7 : []int32{953, 776, 834},
+ 0x1fd8 : []int32{8144},
+ 0x1fd9 : []int32{8145},
+ 0x1fda : []int32{8054},
+ 0x1fdb : []int32{8055},
+ 0x1fe2 : []int32{965, 776, 768},
+ 0x1fe3 : []int32{965, 776, 769},
+ 0x1fe4 : []int32{961, 787},
+ 0x1fe6 : []int32{965, 834},
+ 0x1fe7 : []int32{965, 776, 834},
+ 0x1fe8 : []int32{8160},
+ 0x1fe9 : []int32{8161},
+ 0x1fea : []int32{8058},
+ 0x1feb : []int32{8059},
+ 0x1fec : []int32{8165},
+ 0x1ff2 : []int32{8060, 953},
+ 0x1ff3 : []int32{969, 953},
+ 0x1ff4 : []int32{974, 953},
+ 0x1ff6 : []int32{969, 834},
+ 0x1ff7 : []int32{969, 834, 953},
+ 0x1ff8 : []int32{8056},
+ 0x1ff9 : []int32{8057},
+ 0x1ffa : []int32{8060},
+ 0x1ffb : []int32{8061},
+ 0x1ffc : []int32{969, 953},
+ 0x2126 : []int32{969},
+ 0x212a : []int32{107},
+ 0x212b : []int32{229},
+ 0x2132 : []int32{8526},
+ 0x2160 : []int32{8560},
+ 0x2161 : []int32{8561},
+ 0x2162 : []int32{8562},
+ 0x2163 : []int32{8563},
+ 0x2164 : []int32{8564},
+ 0x2165 : []int32{8565},
+ 0x2166 : []int32{8566},
+ 0x2167 : []int32{8567},
+ 0x2168 : []int32{8568},
+ 0x2169 : []int32{8569},
+ 0x216a : []int32{8570},
+ 0x216b : []int32{8571},
+ 0x216c : []int32{8572},
+ 0x216d : []int32{8573},
+ 0x216e : []int32{8574},
+ 0x216f : []int32{8575},
+ 0x2183 : []int32{8580},
+ 0x24b6 : []int32{9424},
+ 0x24b7 : []int32{9425},
+ 0x24b8 : []int32{9426},
+ 0x24b9 : []int32{9427},
+ 0x24ba : []int32{9428},
+ 0x24bb : []int32{9429},
+ 0x24bc : []int32{9430},
+ 0x24bd : []int32{9431},
+ 0x24be : []int32{9432},
+ 0x24bf : []int32{9433},
+ 0x24c0 : []int32{9434},
+ 0x24c1 : []int32{9435},
+ 0x24c2 : []int32{9436},
+ 0x24c3 : []int32{9437},
+ 0x24c4 : []int32{9438},
+ 0x24c5 : []int32{9439},
+ 0x24c6 : []int32{9440},
+ 0x24c7 : []int32{9441},
+ 0x24c8 : []int32{9442},
+ 0x24c9 : []int32{9443},
+ 0x24ca : []int32{9444},
+ 0x24cb : []int32{9445},
+ 0x24cc : []int32{9446},
+ 0x24cd : []int32{9447},
+ 0x24ce : []int32{9448},
+ 0x24cf : []int32{9449},
+ 0x2c00 : []int32{11312},
+ 0x2c01 : []int32{11313},
+ 0x2c02 : []int32{11314},
+ 0x2c03 : []int32{11315},
+ 0x2c04 : []int32{11316},
+ 0x2c05 : []int32{11317},
+ 0x2c06 : []int32{11318},
+ 0x2c07 : []int32{11319},
+ 0x2c08 : []int32{11320},
+ 0x2c09 : []int32{11321},
+ 0x2c0a : []int32{11322},
+ 0x2c0b : []int32{11323},
+ 0x2c0c : []int32{11324},
+ 0x2c0d : []int32{11325},
+ 0x2c0e : []int32{11326},
+ 0x2c0f : []int32{11327},
+ 0x2c10 : []int32{11328},
+ 0x2c11 : []int32{11329},
+ 0x2c12 : []int32{11330},
+ 0x2c13 : []int32{11331},
+ 0x2c14 : []int32{11332},
+ 0x2c15 : []int32{11333},
+ 0x2c16 : []int32{11334},
+ 0x2c17 : []int32{11335},
+ 0x2c18 : []int32{11336},
+ 0x2c19 : []int32{11337},
+ 0x2c1a : []int32{11338},
+ 0x2c1b : []int32{11339},
+ 0x2c1c : []int32{11340},
+ 0x2c1d : []int32{11341},
+ 0x2c1e : []int32{11342},
+ 0x2c1f : []int32{11343},
+ 0x2c20 : []int32{11344},
+ 0x2c21 : []int32{11345},
+ 0x2c22 : []int32{11346},
+ 0x2c23 : []int32{11347},
+ 0x2c24 : []int32{11348},
+ 0x2c25 : []int32{11349},
+ 0x2c26 : []int32{11350},
+ 0x2c27 : []int32{11351},
+ 0x2c28 : []int32{11352},
+ 0x2c29 : []int32{11353},
+ 0x2c2a : []int32{11354},
+ 0x2c2b : []int32{11355},
+ 0x2c2c : []int32{11356},
+ 0x2c2d : []int32{11357},
+ 0x2c2e : []int32{11358},
+ 0x2c2f : []int32{11359},
+ 0x2c60 : []int32{11361},
+ 0x2c62 : []int32{619},
+ 0x2c63 : []int32{7549},
+ 0x2c64 : []int32{637},
+ 0x2c67 : []int32{11368},
+ 0x2c69 : []int32{11370},
+ 0x2c6b : []int32{11372},
+ 0x2c6d : []int32{593},
+ 0x2c6e : []int32{625},
+ 0x2c6f : []int32{592},
+ 0x2c70 : []int32{594},
+ 0x2c72 : []int32{11379},
+ 0x2c75 : []int32{11382},
+ 0x2c7e : []int32{575},
+ 0x2c7f : []int32{576},
+ 0x2c80 : []int32{11393},
+ 0x2c82 : []int32{11395},
+ 0x2c84 : []int32{11397},
+ 0x2c86 : []int32{11399},
+ 0x2c88 : []int32{11401},
+ 0x2c8a : []int32{11403},
+ 0x2c8c : []int32{11405},
+ 0x2c8e : []int32{11407},
+ 0x2c90 : []int32{11409},
+ 0x2c92 : []int32{11411},
+ 0x2c94 : []int32{11413},
+ 0x2c96 : []int32{11415},
+ 0x2c98 : []int32{11417},
+ 0x2c9a : []int32{11419},
+ 0x2c9c : []int32{11421},
+ 0x2c9e : []int32{11423},
+ 0x2ca0 : []int32{11425},
+ 0x2ca2 : []int32{11427},
+ 0x2ca4 : []int32{11429},
+ 0x2ca6 : []int32{11431},
+ 0x2ca8 : []int32{11433},
+ 0x2caa : []int32{11435},
+ 0x2cac : []int32{11437},
+ 0x2cae : []int32{11439},
+ 0x2cb0 : []int32{11441},
+ 0x2cb2 : []int32{11443},
+ 0x2cb4 : []int32{11445},
+ 0x2cb6 : []int32{11447},
+ 0x2cb8 : []int32{11449},
+ 0x2cba : []int32{11451},
+ 0x2cbc : []int32{11453},
+ 0x2cbe : []int32{11455},
+ 0x2cc0 : []int32{11457},
+ 0x2cc2 : []int32{11459},
+ 0x2cc4 : []int32{11461},
+ 0x2cc6 : []int32{11463},
+ 0x2cc8 : []int32{11465},
+ 0x2cca : []int32{11467},
+ 0x2ccc : []int32{11469},
+ 0x2cce : []int32{11471},
+ 0x2cd0 : []int32{11473},
+ 0x2cd2 : []int32{11475},
+ 0x2cd4 : []int32{11477},
+ 0x2cd6 : []int32{11479},
+ 0x2cd8 : []int32{11481},
+ 0x2cda : []int32{11483},
+ 0x2cdc : []int32{11485},
+ 0x2cde : []int32{11487},
+ 0x2ce0 : []int32{11489},
+ 0x2ce2 : []int32{11491},
+ 0x2ceb : []int32{11500},
+ 0x2ced : []int32{11502},
+ 0x2cf2 : []int32{11507},
+ 0xa640 : []int32{42561},
+ 0xa642 : []int32{42563},
+ 0xa644 : []int32{42565},
+ 0xa646 : []int32{42567},
+ 0xa648 : []int32{42569},
+ 0xa64a : []int32{42571},
+ 0xa64c : []int32{42573},
+ 0xa64e : []int32{42575},
+ 0xa650 : []int32{42577},
+ 0xa652 : []int32{42579},
+ 0xa654 : []int32{42581},
+ 0xa656 : []int32{42583},
+ 0xa658 : []int32{42585},
+ 0xa65a : []int32{42587},
+ 0xa65c : []int32{42589},
+ 0xa65e : []int32{42591},
+ 0xa660 : []int32{42593},
+ 0xa662 : []int32{42595},
+ 0xa664 : []int32{42597},
+ 0xa666 : []int32{42599},
+ 0xa668 : []int32{42601},
+ 0xa66a : []int32{42603},
+ 0xa66c : []int32{42605},
+ 0xa680 : []int32{42625},
+ 0xa682 : []int32{42627},
+ 0xa684 : []int32{42629},
+ 0xa686 : []int32{42631},
+ 0xa688 : []int32{42633},
+ 0xa68a : []int32{42635},
+ 0xa68c : []int32{42637},
+ 0xa68e : []int32{42639},
+ 0xa690 : []int32{42641},
+ 0xa692 : []int32{42643},
+ 0xa694 : []int32{42645},
+ 0xa696 : []int32{42647},
+ 0xa698 : []int32{42649},
+ 0xa69a : []int32{42651},
+ 0xa722 : []int32{42787},
+ 0xa724 : []int32{42789},
+ 0xa726 : []int32{42791},
+ 0xa728 : []int32{42793},
+ 0xa72a : []int32{42795},
+ 0xa72c : []int32{42797},
+ 0xa72e : []int32{42799},
+ 0xa732 : []int32{42803},
+ 0xa734 : []int32{42805},
+ 0xa736 : []int32{42807},
+ 0xa738 : []int32{42809},
+ 0xa73a : []int32{42811},
+ 0xa73c : []int32{42813},
+ 0xa73e : []int32{42815},
+ 0xa740 : []int32{42817},
+ 0xa742 : []int32{42819},
+ 0xa744 : []int32{42821},
+ 0xa746 : []int32{42823},
+ 0xa748 : []int32{42825},
+ 0xa74a : []int32{42827},
+ 0xa74c : []int32{42829},
+ 0xa74e : []int32{42831},
+ 0xa750 : []int32{42833},
+ 0xa752 : []int32{42835},
+ 0xa754 : []int32{42837},
+ 0xa756 : []int32{42839},
+ 0xa758 : []int32{42841},
+ 0xa75a : []int32{42843},
+ 0xa75c : []int32{42845},
+ 0xa75e : []int32{42847},
+ 0xa760 : []int32{42849},
+ 0xa762 : []int32{42851},
+ 0xa764 : []int32{42853},
+ 0xa766 : []int32{42855},
+ 0xa768 : []int32{42857},
+ 0xa76a : []int32{42859},
+ 0xa76c : []int32{42861},
+ 0xa76e : []int32{42863},
+ 0xa779 : []int32{42874},
+ 0xa77b : []int32{42876},
+ 0xa77d : []int32{7545},
+ 0xa77e : []int32{42879},
+ 0xa780 : []int32{42881},
+ 0xa782 : []int32{42883},
+ 0xa784 : []int32{42885},
+ 0xa786 : []int32{42887},
+ 0xa78b : []int32{42892},
+ 0xa78d : []int32{613},
+ 0xa790 : []int32{42897},
+ 0xa792 : []int32{42899},
+ 0xa796 : []int32{42903},
+ 0xa798 : []int32{42905},
+ 0xa79a : []int32{42907},
+ 0xa79c : []int32{42909},
+ 0xa79e : []int32{42911},
+ 0xa7a0 : []int32{42913},
+ 0xa7a2 : []int32{42915},
+ 0xa7a4 : []int32{42917},
+ 0xa7a6 : []int32{42919},
+ 0xa7a8 : []int32{42921},
+ 0xa7aa : []int32{614},
+ 0xa7ab : []int32{604},
+ 0xa7ac : []int32{609},
+ 0xa7ad : []int32{620},
+ 0xa7ae : []int32{618},
+ 0xa7b0 : []int32{670},
+ 0xa7b1 : []int32{647},
+ 0xa7b2 : []int32{669},
+ 0xa7b3 : []int32{43859},
+ 0xa7b4 : []int32{42933},
+ 0xa7b6 : []int32{42935},
+ 0xa7b8 : []int32{42937},
+ 0xa7ba : []int32{42939},
+ 0xa7bc : []int32{42941},
+ 0xa7be : []int32{42943},
+ 0xa7c0 : []int32{42945},
+ 0xa7c2 : []int32{42947},
+ 0xa7c4 : []int32{42900},
+ 0xa7c5 : []int32{642},
+ 0xa7c6 : []int32{7566},
+ 0xa7c7 : []int32{42952},
+ 0xa7c9 : []int32{42954},
+ 0xa7d0 : []int32{42961},
+ 0xa7d6 : []int32{42967},
+ 0xa7d8 : []int32{42969},
+ 0xa7f5 : []int32{42998},
+ 0xab70 : []int32{5024},
+ 0xab71 : []int32{5025},
+ 0xab72 : []int32{5026},
+ 0xab73 : []int32{5027},
+ 0xab74 : []int32{5028},
+ 0xab75 : []int32{5029},
+ 0xab76 : []int32{5030},
+ 0xab77 : []int32{5031},
+ 0xab78 : []int32{5032},
+ 0xab79 : []int32{5033},
+ 0xab7a : []int32{5034},
+ 0xab7b : []int32{5035},
+ 0xab7c : []int32{5036},
+ 0xab7d : []int32{5037},
+ 0xab7e : []int32{5038},
+ 0xab7f : []int32{5039},
+ 0xab80 : []int32{5040},
+ 0xab81 : []int32{5041},
+ 0xab82 : []int32{5042},
+ 0xab83 : []int32{5043},
+ 0xab84 : []int32{5044},
+ 0xab85 : []int32{5045},
+ 0xab86 : []int32{5046},
+ 0xab87 : []int32{5047},
+ 0xab88 : []int32{5048},
+ 0xab89 : []int32{5049},
+ 0xab8a : []int32{5050},
+ 0xab8b : []int32{5051},
+ 0xab8c : []int32{5052},
+ 0xab8d : []int32{5053},
+ 0xab8e : []int32{5054},
+ 0xab8f : []int32{5055},
+ 0xab90 : []int32{5056},
+ 0xab91 : []int32{5057},
+ 0xab92 : []int32{5058},
+ 0xab93 : []int32{5059},
+ 0xab94 : []int32{5060},
+ 0xab95 : []int32{5061},
+ 0xab96 : []int32{5062},
+ 0xab97 : []int32{5063},
+ 0xab98 : []int32{5064},
+ 0xab99 : []int32{5065},
+ 0xab9a : []int32{5066},
+ 0xab9b : []int32{5067},
+ 0xab9c : []int32{5068},
+ 0xab9d : []int32{5069},
+ 0xab9e : []int32{5070},
+ 0xab9f : []int32{5071},
+ 0xaba0 : []int32{5072},
+ 0xaba1 : []int32{5073},
+ 0xaba2 : []int32{5074},
+ 0xaba3 : []int32{5075},
+ 0xaba4 : []int32{5076},
+ 0xaba5 : []int32{5077},
+ 0xaba6 : []int32{5078},
+ 0xaba7 : []int32{5079},
+ 0xaba8 : []int32{5080},
+ 0xaba9 : []int32{5081},
+ 0xabaa : []int32{5082},
+ 0xabab : []int32{5083},
+ 0xabac : []int32{5084},
+ 0xabad : []int32{5085},
+ 0xabae : []int32{5086},
+ 0xabaf : []int32{5087},
+ 0xabb0 : []int32{5088},
+ 0xabb1 : []int32{5089},
+ 0xabb2 : []int32{5090},
+ 0xabb3 : []int32{5091},
+ 0xabb4 : []int32{5092},
+ 0xabb5 : []int32{5093},
+ 0xabb6 : []int32{5094},
+ 0xabb7 : []int32{5095},
+ 0xabb8 : []int32{5096},
+ 0xabb9 : []int32{5097},
+ 0xabba : []int32{5098},
+ 0xabbb : []int32{5099},
+ 0xabbc : []int32{5100},
+ 0xabbd : []int32{5101},
+ 0xabbe : []int32{5102},
+ 0xabbf : []int32{5103},
+ 0xfb00 : []int32{102, 102},
+ 0xfb01 : []int32{102, 105},
+ 0xfb02 : []int32{102, 108},
+ 0xfb03 : []int32{102, 102, 105},
+ 0xfb04 : []int32{102, 102, 108},
+ 0xfb05 : []int32{115, 116},
+ 0xfb06 : []int32{115, 116},
+ 0xfb13 : []int32{1396, 1398},
+ 0xfb14 : []int32{1396, 1381},
+ 0xfb15 : []int32{1396, 1387},
+ 0xfb16 : []int32{1406, 1398},
+ 0xfb17 : []int32{1396, 1389},
+ 0xff21 : []int32{65345},
+ 0xff22 : []int32{65346},
+ 0xff23 : []int32{65347},
+ 0xff24 : []int32{65348},
+ 0xff25 : []int32{65349},
+ 0xff26 : []int32{65350},
+ 0xff27 : []int32{65351},
+ 0xff28 : []int32{65352},
+ 0xff29 : []int32{65353},
+ 0xff2a : []int32{65354},
+ 0xff2b : []int32{65355},
+ 0xff2c : []int32{65356},
+ 0xff2d : []int32{65357},
+ 0xff2e : []int32{65358},
+ 0xff2f : []int32{65359},
+ 0xff30 : []int32{65360},
+ 0xff31 : []int32{65361},
+ 0xff32 : []int32{65362},
+ 0xff33 : []int32{65363},
+ 0xff34 : []int32{65364},
+ 0xff35 : []int32{65365},
+ 0xff36 : []int32{65366},
+ 0xff37 : []int32{65367},
+ 0xff38 : []int32{65368},
+ 0xff39 : []int32{65369},
+ 0xff3a : []int32{65370},
+ 0x10400 : []int32{66600},
+ 0x10401 : []int32{66601},
+ 0x10402 : []int32{66602},
+ 0x10403 : []int32{66603},
+ 0x10404 : []int32{66604},
+ 0x10405 : []int32{66605},
+ 0x10406 : []int32{66606},
+ 0x10407 : []int32{66607},
+ 0x10408 : []int32{66608},
+ 0x10409 : []int32{66609},
+ 0x1040a : []int32{66610},
+ 0x1040b : []int32{66611},
+ 0x1040c : []int32{66612},
+ 0x1040d : []int32{66613},
+ 0x1040e : []int32{66614},
+ 0x1040f : []int32{66615},
+ 0x10410 : []int32{66616},
+ 0x10411 : []int32{66617},
+ 0x10412 : []int32{66618},
+ 0x10413 : []int32{66619},
+ 0x10414 : []int32{66620},
+ 0x10415 : []int32{66621},
+ 0x10416 : []int32{66622},
+ 0x10417 : []int32{66623},
+ 0x10418 : []int32{66624},
+ 0x10419 : []int32{66625},
+ 0x1041a : []int32{66626},
+ 0x1041b : []int32{66627},
+ 0x1041c : []int32{66628},
+ 0x1041d : []int32{66629},
+ 0x1041e : []int32{66630},
+ 0x1041f : []int32{66631},
+ 0x10420 : []int32{66632},
+ 0x10421 : []int32{66633},
+ 0x10422 : []int32{66634},
+ 0x10423 : []int32{66635},
+ 0x10424 : []int32{66636},
+ 0x10425 : []int32{66637},
+ 0x10426 : []int32{66638},
+ 0x10427 : []int32{66639},
+ 0x104b0 : []int32{66776},
+ 0x104b1 : []int32{66777},
+ 0x104b2 : []int32{66778},
+ 0x104b3 : []int32{66779},
+ 0x104b4 : []int32{66780},
+ 0x104b5 : []int32{66781},
+ 0x104b6 : []int32{66782},
+ 0x104b7 : []int32{66783},
+ 0x104b8 : []int32{66784},
+ 0x104b9 : []int32{66785},
+ 0x104ba : []int32{66786},
+ 0x104bb : []int32{66787},
+ 0x104bc : []int32{66788},
+ 0x104bd : []int32{66789},
+ 0x104be : []int32{66790},
+ 0x104bf : []int32{66791},
+ 0x104c0 : []int32{66792},
+ 0x104c1 : []int32{66793},
+ 0x104c2 : []int32{66794},
+ 0x104c3 : []int32{66795},
+ 0x104c4 : []int32{66796},
+ 0x104c5 : []int32{66797},
+ 0x104c6 : []int32{66798},
+ 0x104c7 : []int32{66799},
+ 0x104c8 : []int32{66800},
+ 0x104c9 : []int32{66801},
+ 0x104ca : []int32{66802},
+ 0x104cb : []int32{66803},
+ 0x104cc : []int32{66804},
+ 0x104cd : []int32{66805},
+ 0x104ce : []int32{66806},
+ 0x104cf : []int32{66807},
+ 0x104d0 : []int32{66808},
+ 0x104d1 : []int32{66809},
+ 0x104d2 : []int32{66810},
+ 0x104d3 : []int32{66811},
+ 0x10570 : []int32{66967},
+ 0x10571 : []int32{66968},
+ 0x10572 : []int32{66969},
+ 0x10573 : []int32{66970},
+ 0x10574 : []int32{66971},
+ 0x10575 : []int32{66972},
+ 0x10576 : []int32{66973},
+ 0x10577 : []int32{66974},
+ 0x10578 : []int32{66975},
+ 0x10579 : []int32{66976},
+ 0x1057a : []int32{66977},
+ 0x1057c : []int32{66979},
+ 0x1057d : []int32{66980},
+ 0x1057e : []int32{66981},
+ 0x1057f : []int32{66982},
+ 0x10580 : []int32{66983},
+ 0x10581 : []int32{66984},
+ 0x10582 : []int32{66985},
+ 0x10583 : []int32{66986},
+ 0x10584 : []int32{66987},
+ 0x10585 : []int32{66988},
+ 0x10586 : []int32{66989},
+ 0x10587 : []int32{66990},
+ 0x10588 : []int32{66991},
+ 0x10589 : []int32{66992},
+ 0x1058a : []int32{66993},
+ 0x1058c : []int32{66995},
+ 0x1058d : []int32{66996},
+ 0x1058e : []int32{66997},
+ 0x1058f : []int32{66998},
+ 0x10590 : []int32{66999},
+ 0x10591 : []int32{67000},
+ 0x10592 : []int32{67001},
+ 0x10594 : []int32{67003},
+ 0x10595 : []int32{67004},
+ 0x10c80 : []int32{68800},
+ 0x10c81 : []int32{68801},
+ 0x10c82 : []int32{68802},
+ 0x10c83 : []int32{68803},
+ 0x10c84 : []int32{68804},
+ 0x10c85 : []int32{68805},
+ 0x10c86 : []int32{68806},
+ 0x10c87 : []int32{68807},
+ 0x10c88 : []int32{68808},
+ 0x10c89 : []int32{68809},
+ 0x10c8a : []int32{68810},
+ 0x10c8b : []int32{68811},
+ 0x10c8c : []int32{68812},
+ 0x10c8d : []int32{68813},
+ 0x10c8e : []int32{68814},
+ 0x10c8f : []int32{68815},
+ 0x10c90 : []int32{68816},
+ 0x10c91 : []int32{68817},
+ 0x10c92 : []int32{68818},
+ 0x10c93 : []int32{68819},
+ 0x10c94 : []int32{68820},
+ 0x10c95 : []int32{68821},
+ 0x10c96 : []int32{68822},
+ 0x10c97 : []int32{68823},
+ 0x10c98 : []int32{68824},
+ 0x10c99 : []int32{68825},
+ 0x10c9a : []int32{68826},
+ 0x10c9b : []int32{68827},
+ 0x10c9c : []int32{68828},
+ 0x10c9d : []int32{68829},
+ 0x10c9e : []int32{68830},
+ 0x10c9f : []int32{68831},
+ 0x10ca0 : []int32{68832},
+ 0x10ca1 : []int32{68833},
+ 0x10ca2 : []int32{68834},
+ 0x10ca3 : []int32{68835},
+ 0x10ca4 : []int32{68836},
+ 0x10ca5 : []int32{68837},
+ 0x10ca6 : []int32{68838},
+ 0x10ca7 : []int32{68839},
+ 0x10ca8 : []int32{68840},
+ 0x10ca9 : []int32{68841},
+ 0x10caa : []int32{68842},
+ 0x10cab : []int32{68843},
+ 0x10cac : []int32{68844},
+ 0x10cad : []int32{68845},
+ 0x10cae : []int32{68846},
+ 0x10caf : []int32{68847},
+ 0x10cb0 : []int32{68848},
+ 0x10cb1 : []int32{68849},
+ 0x10cb2 : []int32{68850},
+ 0x118a0 : []int32{71872},
+ 0x118a1 : []int32{71873},
+ 0x118a2 : []int32{71874},
+ 0x118a3 : []int32{71875},
+ 0x118a4 : []int32{71876},
+ 0x118a5 : []int32{71877},
+ 0x118a6 : []int32{71878},
+ 0x118a7 : []int32{71879},
+ 0x118a8 : []int32{71880},
+ 0x118a9 : []int32{71881},
+ 0x118aa : []int32{71882},
+ 0x118ab : []int32{71883},
+ 0x118ac : []int32{71884},
+ 0x118ad : []int32{71885},
+ 0x118ae : []int32{71886},
+ 0x118af : []int32{71887},
+ 0x118b0 : []int32{71888},
+ 0x118b1 : []int32{71889},
+ 0x118b2 : []int32{71890},
+ 0x118b3 : []int32{71891},
+ 0x118b4 : []int32{71892},
+ 0x118b5 : []int32{71893},
+ 0x118b6 : []int32{71894},
+ 0x118b7 : []int32{71895},
+ 0x118b8 : []int32{71896},
+ 0x118b9 : []int32{71897},
+ 0x118ba : []int32{71898},
+ 0x118bb : []int32{71899},
+ 0x118bc : []int32{71900},
+ 0x118bd : []int32{71901},
+ 0x118be : []int32{71902},
+ 0x118bf : []int32{71903},
+ 0x16e40 : []int32{93792},
+ 0x16e41 : []int32{93793},
+ 0x16e42 : []int32{93794},
+ 0x16e43 : []int32{93795},
+ 0x16e44 : []int32{93796},
+ 0x16e45 : []int32{93797},
+ 0x16e46 : []int32{93798},
+ 0x16e47 : []int32{93799},
+ 0x16e48 : []int32{93800},
+ 0x16e49 : []int32{93801},
+ 0x16e4a : []int32{93802},
+ 0x16e4b : []int32{93803},
+ 0x16e4c : []int32{93804},
+ 0x16e4d : []int32{93805},
+ 0x16e4e : []int32{93806},
+ 0x16e4f : []int32{93807},
+ 0x16e50 : []int32{93808},
+ 0x16e51 : []int32{93809},
+ 0x16e52 : []int32{93810},
+ 0x16e53 : []int32{93811},
+ 0x16e54 : []int32{93812},
+ 0x16e55 : []int32{93813},
+ 0x16e56 : []int32{93814},
+ 0x16e57 : []int32{93815},
+ 0x16e58 : []int32{93816},
+ 0x16e59 : []int32{93817},
+ 0x16e5a : []int32{93818},
+ 0x16e5b : []int32{93819},
+ 0x16e5c : []int32{93820},
+ 0x16e5d : []int32{93821},
+ 0x16e5e : []int32{93822},
+ 0x16e5f : []int32{93823},
+ 0x1e900 : []int32{125218},
+ 0x1e901 : []int32{125219},
+ 0x1e902 : []int32{125220},
+ 0x1e903 : []int32{125221},
+ 0x1e904 : []int32{125222},
+ 0x1e905 : []int32{125223},
+ 0x1e906 : []int32{125224},
+ 0x1e907 : []int32{125225},
+ 0x1e908 : []int32{125226},
+ 0x1e909 : []int32{125227},
+ 0x1e90a : []int32{125228},
+ 0x1e90b : []int32{125229},
+ 0x1e90c : []int32{125230},
+ 0x1e90d : []int32{125231},
+ 0x1e90e : []int32{125232},
+ 0x1e90f : []int32{125233},
+ 0x1e910 : []int32{125234},
+ 0x1e911 : []int32{125235},
+ 0x1e912 : []int32{125236},
+ 0x1e913 : []int32{125237},
+ 0x1e914 : []int32{125238},
+ 0x1e915 : []int32{125239},
+ 0x1e916 : []int32{125240},
+ 0x1e917 : []int32{125241},
+ 0x1e918 : []int32{125242},
+ 0x1e919 : []int32{125243},
+ 0x1e91a : []int32{125244},
+ 0x1e91b : []int32{125245},
+ 0x1e91c : []int32{125246},
+ 0x1e91d : []int32{125247},
+ 0x1e91e : []int32{125248},
+ 0x1e91f : []int32{125249},
+ 0x1e920 : []int32{125250},
+ 0x1e921 : []int32{125251},
}
diff --git a/vendor/github.com/yuin/goldmark/util/util.go b/vendor/github.com/yuin/goldmark/util/util.go
index ef113c4ae..a817ec630 100644
--- a/vendor/github.com/yuin/goldmark/util/util.go
+++ b/vendor/github.com/yuin/goldmark/util/util.go
@@ -8,6 +8,7 @@ import (
"regexp"
"sort"
"strconv"
+ "unicode"
"unicode/utf8"
)
@@ -27,6 +28,7 @@ func NewCopyOnWriteBuffer(buffer []byte) CopyOnWriteBuffer {
}
// Write writes given bytes to the buffer.
+// Write allocate new buffer and clears it at the first time.
func (b *CopyOnWriteBuffer) Write(value []byte) {
if !b.copied {
b.buffer = make([]byte, 0, len(b.buffer)+20)
@@ -35,7 +37,32 @@ func (b *CopyOnWriteBuffer) Write(value []byte) {
b.buffer = append(b.buffer, value...)
}
+// WriteString writes given string to the buffer.
+// WriteString allocate new buffer and clears it at the first time.
+func (b *CopyOnWriteBuffer) WriteString(value string) {
+ b.Write(StringToReadOnlyBytes(value))
+}
+
+// Append appends given bytes to the buffer.
+// Append copy buffer at the first time.
+func (b *CopyOnWriteBuffer) Append(value []byte) {
+ if !b.copied {
+ tmp := make([]byte, len(b.buffer), len(b.buffer)+20)
+ copy(tmp, b.buffer)
+ b.buffer = tmp
+ b.copied = true
+ }
+ b.buffer = append(b.buffer, value...)
+}
+
+// AppendString appends given string to the buffer.
+// AppendString copy buffer at the first time.
+func (b *CopyOnWriteBuffer) AppendString(value string) {
+ b.Append(StringToReadOnlyBytes(value))
+}
+
// WriteByte writes the given byte to the buffer.
+// WriteByte allocate new buffer and clears it at the first time.
func (b *CopyOnWriteBuffer) WriteByte(c byte) {
if !b.copied {
b.buffer = make([]byte, 0, len(b.buffer)+20)
@@ -44,6 +71,18 @@ func (b *CopyOnWriteBuffer) WriteByte(c byte) {
b.buffer = append(b.buffer, c)
}
+// AppendByte appends given bytes to the buffer.
+// AppendByte copy buffer at the first time.
+func (b *CopyOnWriteBuffer) AppendByte(c byte) {
+ if !b.copied {
+ tmp := make([]byte, len(b.buffer), len(b.buffer)+20)
+ copy(tmp, b.buffer)
+ b.buffer = tmp
+ b.copied = true
+ }
+ b.buffer = append(b.buffer, c)
+}
+
// Bytes returns bytes of this buffer.
func (b *CopyOnWriteBuffer) Bytes() []byte {
return b.buffer
@@ -91,6 +130,9 @@ func VisualizeSpaces(bs []byte) []byte {
bs = bytes.Replace(bs, []byte("\t"), []byte("[TAB]"), -1)
bs = bytes.Replace(bs, []byte("\n"), []byte("[NEWLINE]\n"), -1)
bs = bytes.Replace(bs, []byte("\r"), []byte("[CR]"), -1)
+ bs = bytes.Replace(bs, []byte("\v"), []byte("[VTAB]"), -1)
+ bs = bytes.Replace(bs, []byte("\x00"), []byte("[NUL]"), -1)
+ bs = bytes.Replace(bs, []byte("\ufffd"), []byte("[U+FFFD]"), -1)
return bs
}
@@ -110,30 +152,7 @@ func TabWidth(currentPos int) int {
// width=2 is in the tab character. In this case, IndentPosition returns
// (pos=1, padding=2)
func IndentPosition(bs []byte, currentPos, width int) (pos, padding int) {
- if width == 0 {
- return 0, 0
- }
- w := 0
- l := len(bs)
- i := 0
- hasTab := false
- for ; i < l; i++ {
- if bs[i] == '\t' {
- w += TabWidth(currentPos + w)
- hasTab = true
- } else if bs[i] == ' ' {
- w++
- } else {
- break
- }
- }
- if w >= width {
- if !hasTab {
- return width, 0
- }
- return i, w - width
- }
- return -1, -1
+ return IndentPositionPadding(bs, currentPos, 0, width)
}
// IndentPositionPadding searches an indent position with the given width for the given line.
@@ -147,9 +166,9 @@ func IndentPositionPadding(bs []byte, currentPos, paddingv, width int) (pos, pad
i := 0
l := len(bs)
for ; i < l; i++ {
- if bs[i] == '\t' {
+ if bs[i] == '\t' && w < width {
w += TabWidth(currentPos + w)
- } else if bs[i] == ' ' {
+ } else if bs[i] == ' ' && w < width {
w++
} else {
break
@@ -162,52 +181,56 @@ func IndentPositionPadding(bs []byte, currentPos, paddingv, width int) (pos, pad
}
// DedentPosition dedents lines by the given width.
+//
+// Deprecated: This function has bugs. Use util.IndentPositionPadding and util.FirstNonSpacePosition.
func DedentPosition(bs []byte, currentPos, width int) (pos, padding int) {
- if width == 0 {
- return 0, 0
- }
- w := 0
- l := len(bs)
- i := 0
- for ; i < l; i++ {
- if bs[i] == '\t' {
- w += TabWidth(currentPos + w)
- } else if bs[i] == ' ' {
- w++
- } else {
- break
- }
- }
- if w >= width {
- return i, w - width
- }
- return i, 0
+ if width == 0 {
+ return 0, 0
+ }
+ w := 0
+ l := len(bs)
+ i := 0
+ for ; i < l; i++ {
+ if bs[i] == '\t' {
+ w += TabWidth(currentPos + w)
+ } else if bs[i] == ' ' {
+ w++
+ } else {
+ break
+ }
+ }
+ if w >= width {
+ return i, w - width
+ }
+ return i, 0
}
// DedentPositionPadding dedents lines by the given width.
// This function is mostly same as DedentPosition except this function
// takes account into additional paddings.
+//
+// Deprecated: This function has bugs. Use util.IndentPositionPadding and util.FirstNonSpacePosition.
func DedentPositionPadding(bs []byte, currentPos, paddingv, width int) (pos, padding int) {
- if width == 0 {
- return 0, paddingv
- }
-
- w := 0
- i := 0
- l := len(bs)
- for ; i < l; i++ {
- if bs[i] == '\t' {
- w += TabWidth(currentPos + w)
- } else if bs[i] == ' ' {
- w++
- } else {
- break
- }
- }
- if w >= width {
- return i - paddingv, w - width
- }
- return i - paddingv, 0
+ if width == 0 {
+ return 0, paddingv
+ }
+
+ w := 0
+ i := 0
+ l := len(bs)
+ for ; i < l; i++ {
+ if bs[i] == '\t' {
+ w += TabWidth(currentPos + w)
+ } else if bs[i] == ' ' {
+ w++
+ } else {
+ break
+ }
+ }
+ if w >= width {
+ return i - paddingv, w - width
+ }
+ return i - paddingv, 0
}
// IndentWidth calculate an indent width for the given line.
@@ -249,6 +272,10 @@ func FirstNonSpacePosition(bs []byte) int {
// If codeSpan is set true, it ignores characters in code spans.
// If allowNesting is set true, closures correspond to nested opener will be
// ignored.
+//
+// Deprecated: This function can not handle newlines. Many elements
+// can be existed over multiple lines(e.g. link labels).
+// Use text.Reader.FindClosure.
func FindClosure(bs []byte, opener, closure byte, codeSpan, allowNesting bool) int {
i := 0
opened := 1
@@ -668,7 +695,7 @@ func URLEscape(v []byte, resolveReference bool) []byte {
n = i
continue
}
- if int(u8len) >= len(v) {
+ if int(u8len) > len(v) {
u8len = int8(len(v) - 1)
}
if u8len == 0 {
@@ -754,7 +781,7 @@ func FindEmailIndex(b []byte) int {
var spaces = []byte(" \t\n\x0b\x0c\x0d")
-var spaceTable = [256]int8{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+var spaceTable = [256]int8{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
var punctTable = [256]int8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
@@ -777,11 +804,21 @@ func IsPunct(c byte) bool {
return punctTable[c] == 1
}
+// IsPunctRune returns true if the given rune is a punctuation, otherwise false.
+func IsPunctRune(r rune) bool {
+ return int32(r) <= 256 && IsPunct(byte(r)) || unicode.IsPunct(r)
+}
+
// IsSpace returns true if the given character is a space, otherwise false.
func IsSpace(c byte) bool {
return spaceTable[c] == 1
}
+// IsSpaceRune returns true if the given rune is a space, otherwise false.
+func IsSpaceRune(r rune) bool {
+ return int32(r) <= 256 && IsSpace(byte(r)) || unicode.IsSpace(r)
+}
+
// IsNumeric returns true if the given character is a numeric, otherwise false.
func IsNumeric(c byte) bool {
return c >= '0' && c <= '9'
diff --git a/vendor/github.com/yuin/goldmark/util/util_unsafe.go b/vendor/github.com/yuin/goldmark/util/util_unsafe.go
index beeae2936..d09881104 100644
--- a/vendor/github.com/yuin/goldmark/util/util_unsafe.go
+++ b/vendor/github.com/yuin/goldmark/util/util_unsafe.go
@@ -13,8 +13,11 @@ func BytesToReadOnlyString(b []byte) string {
}
// StringToReadOnlyBytes returns bytes converted from given string.
-func StringToReadOnlyBytes(s string) []byte {
+func StringToReadOnlyBytes(s string) (bs []byte) {
sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
- bh := reflect.SliceHeader{Data: sh.Data, Len: sh.Len, Cap: sh.Len}
- return *(*[]byte)(unsafe.Pointer(&bh))
+ bh := (*reflect.SliceHeader)(unsafe.Pointer(&bs))
+ bh.Data = sh.Data
+ bh.Cap = sh.Len
+ bh.Len = sh.Len
+ return
}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 2f4348f65..386744f99 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -853,7 +853,7 @@ github.com/xdg/stringprep
# github.com/yohcop/openid-go v1.0.0
## explicit
github.com/yohcop/openid-go
-# github.com/yuin/goldmark v1.1.30
+# github.com/yuin/goldmark v1.4.13
## explicit
github.com/yuin/goldmark
github.com/yuin/goldmark/ast
|