visuddhinanda 2 місяців тому
батько
коміт
b8c1febd50
83 змінених файлів з 5969 додано та 0 видалено
  1. 20 0
      api-v12/resources/lang/en/auth.php
  2. 5 0
      api-v12/resources/lang/en/buttons.php
  3. 5 0
      api-v12/resources/lang/en/labels.php
  4. 9 0
      api-v12/resources/lang/en/language.php
  5. 19 0
      api-v12/resources/lang/en/pagination.php
  6. 22 0
      api-v12/resources/lang/en/passwords.php
  7. 22 0
      api-v12/resources/lang/en/site.php
  8. 162 0
      api-v12/resources/lang/en/validation.php
  9. 20 0
      api-v12/resources/lang/zh-Hans/auth.php
  10. 5 0
      api-v12/resources/lang/zh-Hans/buttons.php
  11. 199 0
      api-v12/resources/lang/zh-Hans/grammar.php
  12. 4 0
      api-v12/resources/lang/zh-Hans/label.php
  13. 5 0
      api-v12/resources/lang/zh-Hans/labels.php
  14. 19 0
      api-v12/resources/lang/zh-Hans/pagination.php
  15. 22 0
      api-v12/resources/lang/zh-Hans/passwords.php
  16. 22 0
      api-v12/resources/lang/zh-Hans/site.php
  17. 162 0
      api-v12/resources/lang/zh-Hans/validation.php
  18. 20 0
      api-v12/resources/lang/zh-Hant/auth.php
  19. 5 0
      api-v12/resources/lang/zh-Hant/buttons.php
  20. 5 0
      api-v12/resources/lang/zh-Hant/labels.php
  21. 19 0
      api-v12/resources/lang/zh-Hant/pagination.php
  22. 22 0
      api-v12/resources/lang/zh-Hant/passwords.php
  23. 22 0
      api-v12/resources/lang/zh-Hant/site.php
  24. 162 0
      api-v12/resources/lang/zh-Hant/validation.php
  25. 6 0
      api-v12/resources/mustache/article/html/footnote.html
  26. 9 0
      api-v12/resources/mustache/article/html/glossary.html
  27. 87 0
      api-v12/resources/mustache/article/html/main.html
  28. 5 0
      api-v12/resources/mustache/article/html/section.html
  29. 3 0
      api-v12/resources/mustache/article/md/footnote.md
  30. 9 0
      api-v12/resources/mustache/article/md/glossary.md
  31. 3 0
      api-v12/resources/mustache/article/md/main.md
  32. 8 0
      api-v12/resources/mustache/article/md/section.md
  33. 6 0
      api-v12/resources/mustache/chapter/html/footnote.html
  34. 15 0
      api-v12/resources/mustache/chapter/html/glossary.html
  35. 51 0
      api-v12/resources/mustache/chapter/html/main.html
  36. 6 0
      api-v12/resources/mustache/chapter/html/paragraph.html
  37. 3 0
      api-v12/resources/mustache/chapter/html/section.html
  38. 6 0
      api-v12/resources/mustache/chapter/html/sentence.html
  39. 3 0
      api-v12/resources/mustache/chapter/md/footnote.md
  40. 15 0
      api-v12/resources/mustache/chapter/md/glossary.md
  41. 3 0
      api-v12/resources/mustache/chapter/md/main.md
  42. 8 0
      api-v12/resources/mustache/chapter/md/paragraph.md
  43. 4 0
      api-v12/resources/mustache/chapter/md/section.md
  44. 7 0
      api-v12/resources/mustache/chapter/md/sentence.md
  45. 20 0
      api-v12/resources/mustache/chapter/tex/main.tex
  46. 6 0
      api-v12/resources/mustache/chapter/tex/paragraph.tex
  47. 3 0
      api-v12/resources/mustache/chapter/tex/section.tex
  48. 5 0
      api-v12/resources/mustache/chapter/tex/sentence.tex
  49. 158 0
      api-v12/resources/mustache/my_han_crop.tpl
  50. 11 0
      api-v12/resources/mustache/nissaya_ending_card.tpl
  51. BIN
      api-v12/resources/template/docx/paper.docx
  52. 323 0
      api-v12/resources/views/ananke.blade.php
  53. 56 0
      api-v12/resources/views/blog/category.blade.php
  54. 453 0
      api-v12/resources/views/blog/index.blade.php
  55. 490 0
      api-v12/resources/views/blog/layouts/app.blade.php
  56. 74 0
      api-v12/resources/views/book.blade.php
  57. 28 0
      api-v12/resources/views/components/book-item.blade.php
  58. 118 0
      api-v12/resources/views/components/book-list.blade.php
  59. 29 0
      api-v12/resources/views/components/language-switcher.blade.php
  60. 15 0
      api-v12/resources/views/emails/certification/en-US.blade.php
  61. 15 0
      api-v12/resources/views/emails/certification/en.blade.php
  62. 18 0
      api-v12/resources/views/emails/certification/zh-Hans.blade.php
  63. 15 0
      api-v12/resources/views/emails/certification/zh-Hant.blade.php
  64. 13 0
      api-v12/resources/views/emails/invite/en-US.blade.php
  65. 14 0
      api-v12/resources/views/emails/invite/en.blade.php
  66. 12 0
      api-v12/resources/views/emails/invite/zh-Hans.blade.php
  67. 12 0
      api-v12/resources/views/emails/invite/zh-Hant.blade.php
  68. 13 0
      api-v12/resources/views/emails/reset_password/en-US.blade.php
  69. 13 0
      api-v12/resources/views/emails/reset_password/en.blade.php
  70. 14 0
      api-v12/resources/views/emails/reset_password/zh-Hans.blade.php
  71. 13 0
      api-v12/resources/views/emails/reset_password/zh-Hant.blade.php
  72. 40 0
      api-v12/resources/views/export_wbw.blade.php
  73. 7 0
      api-v12/resources/views/home.blade.php
  74. 492 0
      api-v12/resources/views/library/book/read.blade.php
  75. 143 0
      api-v12/resources/views/library/book/show.blade.php
  76. 59 0
      api-v12/resources/views/library/category.blade.php
  77. 42 0
      api-v12/resources/views/library/index.blade.php
  78. 192 0
      api-v12/resources/views/library/layouts/app.blade.php
  79. 534 0
      api-v12/resources/views/nissaya_format_converter.blade.php
  80. 9 0
      api-v12/resources/views/privacy.blade.php
  81. 397 0
      api-v12/resources/views/solarize.blade.php
  82. 860 0
      api-v12/resources/views/typhoon.blade.php
  83. 19 0
      api-v12/resources/views/wbwanalyses.blade.php

+ 20 - 0
api-v12/resources/lang/en/auth.php

@@ -0,0 +1,20 @@
+<?php
+
+return [
+
+    /*
+    |--------------------------------------------------------------------------
+    | Authentication Language Lines
+    |--------------------------------------------------------------------------
+    |
+    | The following language lines are used during authentication for various
+    | messages that we need to display to the user. You are free to modify
+    | these language lines according to your application's requirements.
+    |
+    */
+
+    'failed' => 'These credentials do not match our records.',
+    'password' => 'The provided password is incorrect.',
+    'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
+
+];

+ 5 - 0
api-v12/resources/lang/en/buttons.php

@@ -0,0 +1,5 @@
+<?php
+return [
+    'more' => 'More',
+    'online-read' =>  'Online Read',
+];

+ 5 - 0
api-v12/resources/lang/en/labels.php

@@ -0,0 +1,5 @@
+<?php
+return [
+    'home' => 'Home',
+    'translation' => 'Translation',
+];

+ 9 - 0
api-v12/resources/lang/en/language.php

@@ -0,0 +1,9 @@
+<?php
+return [
+    'en' => 'English',
+    'pali' => 'pali',
+    'zh' => '中文',
+    'zh-Hans' => '简体中文',
+    'zh-Hant' => '繁体中文',
+    'my' => 'မြန်မာဘာသာ',
+];

+ 19 - 0
api-v12/resources/lang/en/pagination.php

@@ -0,0 +1,19 @@
+<?php
+
+return [
+
+    /*
+    |--------------------------------------------------------------------------
+    | Pagination Language Lines
+    |--------------------------------------------------------------------------
+    |
+    | The following language lines are used by the paginator library to build
+    | the simple pagination links. You are free to change them to anything
+    | you want to customize your views to better match your application.
+    |
+    */
+
+    'previous' => '&laquo; Previous',
+    'next' => 'Next &raquo;',
+
+];

+ 22 - 0
api-v12/resources/lang/en/passwords.php

@@ -0,0 +1,22 @@
+<?php
+
+return [
+
+    /*
+    |--------------------------------------------------------------------------
+    | Password Reset Language Lines
+    |--------------------------------------------------------------------------
+    |
+    | The following language lines are the default lines which match reasons
+    | that are given by the password broker for a password update attempt
+    | has failed, such as for an invalid token or invalid new password.
+    |
+    */
+
+    'reset' => 'Your password has been reset!',
+    'sent' => 'We have emailed your password reset link!',
+    'throttled' => 'Please wait before retrying.',
+    'token' => 'This password reset token is invalid.',
+    'user' => "We can't find a user with that email address.",
+
+];

+ 22 - 0
api-v12/resources/lang/en/site.php

@@ -0,0 +1,22 @@
+<?php
+
+return [
+
+    /*
+    |--------------------------------------------------------------------------
+    | site Language Lines
+    |--------------------------------------------------------------------------
+    |
+    |
+    */
+
+    'logo' => '/logo.png',
+    'title' => 'wikipali',
+    'subhead' => 'wikipali',
+    'keywords' => ['pali','buddhistm'],
+    'description' => 'wikipali',
+    'copyright' => 'iapt 2022',
+    'author.name' => 'iapt',
+    'author.email' => 'visuddhindand@gmail.com',
+
+];

+ 162 - 0
api-v12/resources/lang/en/validation.php

@@ -0,0 +1,162 @@
+<?php
+
+return [
+
+    /*
+    |--------------------------------------------------------------------------
+    | Validation Language Lines
+    |--------------------------------------------------------------------------
+    |
+    | The following language lines contain the default error messages used by
+    | the validator class. Some of these rules have multiple versions such
+    | as the size rules. Feel free to tweak each of these messages here.
+    |
+    */
+
+    'accepted' => 'The :attribute must be accepted.',
+    'accepted_if' => 'The :attribute must be accepted when :other is :value.',
+    'active_url' => 'The :attribute is not a valid URL.',
+    'after' => 'The :attribute must be a date after :date.',
+    'after_or_equal' => 'The :attribute must be a date after or equal to :date.',
+    'alpha' => 'The :attribute must only contain letters.',
+    'alpha_dash' => 'The :attribute must only contain letters, numbers, dashes and underscores.',
+    'alpha_num' => 'The :attribute must only contain letters and numbers.',
+    'array' => 'The :attribute must be an array.',
+    'before' => 'The :attribute must be a date before :date.',
+    'before_or_equal' => 'The :attribute must be a date before or equal to :date.',
+    'between' => [
+        'numeric' => 'The :attribute must be between :min and :max.',
+        'file' => 'The :attribute must be between :min and :max kilobytes.',
+        'string' => 'The :attribute must be between :min and :max characters.',
+        'array' => 'The :attribute must have between :min and :max items.',
+    ],
+    'boolean' => 'The :attribute field must be true or false.',
+    'confirmed' => 'The :attribute confirmation does not match.',
+    'current_password' => 'The password is incorrect.',
+    'date' => 'The :attribute is not a valid date.',
+    'date_equals' => 'The :attribute must be a date equal to :date.',
+    'date_format' => 'The :attribute does not match the format :format.',
+    'declined' => 'The :attribute must be declined.',
+    'declined_if' => 'The :attribute must be declined when :other is :value.',
+    'different' => 'The :attribute and :other must be different.',
+    'digits' => 'The :attribute must be :digits digits.',
+    'digits_between' => 'The :attribute must be between :min and :max digits.',
+    'dimensions' => 'The :attribute has invalid image dimensions.',
+    'distinct' => 'The :attribute field has a duplicate value.',
+    'email' => 'The :attribute must be a valid email address.',
+    'ends_with' => 'The :attribute must end with one of the following: :values.',
+    'enum' => 'The selected :attribute is invalid.',
+    'exists' => 'The selected :attribute is exists.',
+    'file' => 'The :attribute must be a file.',
+    'filled' => 'The :attribute field must have a value.',
+    'gt' => [
+        'numeric' => 'The :attribute must be greater than :value.',
+        'file' => 'The :attribute must be greater than :value kilobytes.',
+        'string' => 'The :attribute must be greater than :value characters.',
+        'array' => 'The :attribute must have more than :value items.',
+    ],
+    'gte' => [
+        'numeric' => 'The :attribute must be greater than or equal to :value.',
+        'file' => 'The :attribute must be greater than or equal to :value kilobytes.',
+        'string' => 'The :attribute must be greater than or equal to :value characters.',
+        'array' => 'The :attribute must have :value items or more.',
+    ],
+    'image' => 'The :attribute must be an image.',
+    'in' => 'The selected :attribute is invalid.',
+    'in_array' => 'The :attribute field does not exist in :other.',
+    'integer' => 'The :attribute must be an integer.',
+    'ip' => 'The :attribute must be a valid IP address.',
+    'ipv4' => 'The :attribute must be a valid IPv4 address.',
+    'ipv6' => 'The :attribute must be a valid IPv6 address.',
+    'mac_address' => 'The :attribute must be a valid MAC address.',
+    'json' => 'The :attribute must be a valid JSON string.',
+    'lt' => [
+        'numeric' => 'The :attribute must be less than :value.',
+        'file' => 'The :attribute must be less than :value kilobytes.',
+        'string' => 'The :attribute must be less than :value characters.',
+        'array' => 'The :attribute must have less than :value items.',
+    ],
+    'lte' => [
+        'numeric' => 'The :attribute must be less than or equal to :value.',
+        'file' => 'The :attribute must be less than or equal to :value kilobytes.',
+        'string' => 'The :attribute must be less than or equal to :value characters.',
+        'array' => 'The :attribute must not have more than :value items.',
+    ],
+    'max' => [
+        'numeric' => 'The :attribute must not be greater than :max.',
+        'file' => 'The :attribute must not be greater than :max kilobytes.',
+        'string' => 'The :attribute must not be greater than :max characters.',
+        'array' => 'The :attribute must not have more than :max items.',
+    ],
+    'mimes' => 'The :attribute must be a file of type: :values.',
+    'mimetypes' => 'The :attribute must be a file of type: :values.',
+    'min' => [
+        'numeric' => 'The :attribute must be at least :min.',
+        'file' => 'The :attribute must be at least :min kilobytes.',
+        'string' => 'The :attribute must be at least :min characters.',
+        'array' => 'The :attribute must have at least :min items.',
+    ],
+    'multiple_of' => 'The :attribute must be a multiple of :value.',
+    'not_in' => 'The selected :attribute is invalid.',
+    'not_regex' => 'The :attribute format is invalid.',
+    'numeric' => 'The :attribute must be a number.',
+    'password' => 'The password is incorrect.',
+    'present' => 'The :attribute field must be present.',
+    'prohibited' => 'The :attribute field is prohibited.',
+    'prohibited_if' => 'The :attribute field is prohibited when :other is :value.',
+    'prohibited_unless' => 'The :attribute field is prohibited unless :other is in :values.',
+    'prohibits' => 'The :attribute field prohibits :other from being present.',
+    'regex' => 'The :attribute format is invalid.',
+    'required' => 'The :attribute field is required.',
+    'required_if' => 'The :attribute field is required when :other is :value.',
+    'required_unless' => 'The :attribute field is required unless :other is in :values.',
+    'required_with' => 'The :attribute field is required when :values is present.',
+    'required_with_all' => 'The :attribute field is required when :values are present.',
+    'required_without' => 'The :attribute field is required when :values is not present.',
+    'required_without_all' => 'The :attribute field is required when none of :values are present.',
+    'same' => 'The :attribute and :other must match.',
+    'size' => [
+        'numeric' => 'The :attribute must be :size.',
+        'file' => 'The :attribute must be :size kilobytes.',
+        'string' => 'The :attribute must be :size characters.',
+        'array' => 'The :attribute must contain :size items.',
+    ],
+    'starts_with' => 'The :attribute must start with one of the following: :values.',
+    'string' => 'The :attribute must be a string.',
+    'timezone' => 'The :attribute must be a valid timezone.',
+    'unique' => 'The :attribute has already been taken.',
+    'uploaded' => 'The :attribute failed to upload.',
+    'url' => 'The :attribute must be a valid URL.',
+    'uuid' => 'The :attribute must be a valid UUID.',
+
+    /*
+    |--------------------------------------------------------------------------
+    | Custom Validation Language Lines
+    |--------------------------------------------------------------------------
+    |
+    | Here you may specify custom validation messages for attributes using the
+    | convention "attribute.rule" to name the lines. This makes it quick to
+    | specify a specific custom language line for a given attribute rule.
+    |
+    */
+
+    'custom' => [
+        'attribute-name' => [
+            'rule-name' => 'custom-message',
+        ],
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | Custom Validation Attributes
+    |--------------------------------------------------------------------------
+    |
+    | The following language lines are used to swap our attribute placeholder
+    | with something more reader friendly such as "E-Mail Address" instead
+    | of "email". This simply helps us make our message more expressive.
+    |
+    */
+
+    'attributes' => [],
+
+];

+ 20 - 0
api-v12/resources/lang/zh-Hans/auth.php

@@ -0,0 +1,20 @@
+<?php
+
+return [
+
+    /*
+    |--------------------------------------------------------------------------
+    | Authentication Language Lines
+    |--------------------------------------------------------------------------
+    |
+    | The following language lines are used during authentication for various
+    | messages that we need to display to the user. You are free to modify
+    | these language lines according to your application's requirements.
+    |
+    */
+
+    'failed' => 'These credentials do not match our records.',
+    'password' => 'The provided password is incorrect.',
+    'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
+
+];

+ 5 - 0
api-v12/resources/lang/zh-Hans/buttons.php

@@ -0,0 +1,5 @@
+<?php
+return [
+    'more' => '更多',
+    'online-read' =>  '在线阅读',
+];

+ 199 - 0
api-v12/resources/lang/zh-Hans/grammar.php

@@ -0,0 +1,199 @@
+<?php
+
+return [
+
+    /*
+    |--------------------------------------------------------------------------
+    | site Language Lines
+    |--------------------------------------------------------------------------
+    |
+    |
+    */
+
+    'n' => '名词',
+    'n.short' => '名',
+    'ti' => '三性',
+    'ti.short' => '三',
+    'v' => '动词',
+    'v.short' => '动',
+    'v:ind' => '动不变',
+    'v:ind.short' => '动不变',
+    'ind' => '不变',
+    'ind.short' => '不',
+    'm' => '阳性',
+    'm.short' => '阳',
+    'nt' => '中性',
+    'nt.short' => '中',
+    'f' => '阴性',
+    'f.short' => '阴',
+    'sg' => '单数',
+    'sg.short' => '单',
+    'pl' => '复数',
+    'pl.short' => '复',
+    'nom' => '主格',
+    'nom.short' => '主',
+    'acc' => '宾格',
+    'acc.short' => '宾',
+    'gen' => '属格',
+    'gen.short' => '属',
+    'dat' => '为格',
+    'dat.short' => '为',
+    'inst' => '工具格',
+    'inst.short' => '具',
+    'voc' => '呼格',
+    'voc.short' => '呼',
+    'abl' => '来源格',
+    'abl.short' => '源',
+    'loc' => '处格',
+    'loc.short' => '处',
+    'base' => '词干',
+    'base.short' => '干',
+    'imp' => '命令',
+    'imp.short' => '命令',
+    'cond' => '条件',
+    'cond.short' => '条件',
+    'opt' => '愿望',
+    'opt.short' => '愿望',
+    'pres' => '现',
+    'pres.short' => '现',
+    'aor' => '过',
+    'aor.short' => '过',
+    'pf' => '完',
+    'pf.short' => '完',
+    'fut' => '将',
+    'fut.short' => '将',
+    'act' => '主动',
+    'act.short' => '主动',
+    'refl' => '反照',
+    'refl.short' => '反',
+    '1p' => '第一',
+    '1p.short' => '一',
+    '2p' => '第二',
+    '2p.short' => '二',
+    '3p' => '第三',
+    '3p.short' => '三',
+    'prp' => '现在分词',
+    'prp.short' => '现分',
+    'prpp' => '被动现在分词',
+    'prpp.short' => '被现分',
+    'pp' => '过去分词',
+    'pp.short' => '过分',
+    'ppa' => '主过分',
+    'ppa.short' => '主过分',
+    'ppp' => '被过分',
+    'ppp.short' => '被过分',
+    'futp' => '未来分词',
+    'futp.short' => '未分',
+    'fpa.short' => '主未分',
+    'grd' => '义务',
+    'grd.short' => '义务',
+    'pass' => '被动',
+    'pass.short' => '被动',
+    'caus' => '使役',
+    'caus.short' => '使役',
+    'desid' => '意欲',
+    'desid.short' => '意欲',
+    'intens' => '强意',
+    'intens.short' => '强意',
+    'denom' => '名动',
+    'denom.short' => '名动',
+    'ger' => '连续',
+    'ger.short' => '连续',
+    'abs' => '绝对',
+    'abs.short' => '绝对',
+    'inf' => '不定',
+    'inf.short' => '不定',
+    'adj' => '形容词',
+    'adj.short' => '形',
+    'pron' => '代词',
+    'pron.short' => '代',
+    'num' => '数词',
+    'num.short' => '数',
+    'adv' => '副词',
+    'adv.short' => '副',
+    'conj' => '连词',
+    'conj.short' => '连',
+    'prep' => '介词',
+    'prep.short' => '介',
+    'interj' => '感叹',
+    'interj.short' => '感',
+    'pre' => '前缀',
+    'pre.short' => '前',
+    'suf' => '后缀',
+    'suf.short' => '后',
+    'end' => '语尾',
+    'end.short' => '尾',
+    'part' => '组份',
+    'part.short' => '合',
+    'un' => '连音',
+    'un.short' => '连音',
+    'none' => '无',
+    'none.short' => '_',
+    'null' => '空',
+    'null.short' => '_',
+    '?' => '?',
+    '?.short' => '?',
+    'ti:base' => '三性词干',
+    'ti:base.short' => '三性词干',
+    'n:base' => '名词干',
+    'n:base.short' => '名词干',
+    'v:base' => '动词干',
+    'v:base.short' => '动词干',
+    'adj:base' => '形词干',
+    'adj:base.short' => '形词干',
+    'fpp' => '未来被动分词',
+    'fpp.short' => '未被分',
+    'cp.short' => '合',
+    'cp' => '复合词组分',
+    'indconj.short' => '连',
+    'indconj' => '连词',
+    'pron:base.short' => '代干',
+    'pron:base' => '代词词干',
+    'note.short' => '注释',
+    'note' => '注释',
+    'vind.short' => '动不变',
+    'vind' => '动不变',
+    'vdn' => '衍生动名词',
+    'vdn.short' => '动名',
+    "relations.iad.label" => "同类修饰",
+    "relations.asv.label" => "施动者➡动词",
+    "relations.aov.label" => "受动者➡动词",
+    "relations.daso-p.label" => "主语➡系动词",
+    "relations.daso-s.label" => "表语➡系动词",
+    "relations.nio.label" => "被描述(主)➡定性(表)",
+    "relations.nid.label" => "待命名➡命名",
+    "relations.dasd-p.label" => "<命名>主➡系",
+    "relations.dasd-s.label" => "<命名>表➡系",
+    "relations.dao-p.label" => "被动语态双宾语-首要",
+    "relations.dao-s.label" => "被动语态双宾语-次要",
+    "relations.iov.label" => "受动者➡动词",
+    "relations.dio-p.label" => "双宾语<主要>➡动词",
+    "relations.dio-s.label" => "双宾语<次要>➡动词",
+    "relations.dis-p.label" => "主➡系(被动)",
+    "relations.dis-s.label" => "表➡系(被动)",
+    "relations.stc.label" => "时空连续 ➡ 持续动作",
+    "relations.adv.label" => "动词修饰词 ➡ 动词",
+    "relations.imp.label" => "方式 ➡ 动词",
+    "relations.soe.label" => "<带连词>伴随关系",
+    "relations.soi.label" => "<无连词>伴随关系",
+    "relations.isv.label" => "<非主格>施动者 ➡ 动词",
+    "relations.cau.label" => "因 ➡ 果/归因",
+    "relations.iov-c.label" => "被使役宾语 ➡ 动词",
+    "relations.adj.label" => "名词的形容 ➡ 被形容",
+    "relations.rec.label" => "接收者 ➡ 授予",
+    "relations.pur.label" => "目的 ➡ 动词",
+    "relations.det.label" => "出发地 ➡ 出发",
+    "relations.coc.label" => "区分比较",
+    "relations.pos.label" => "所有 ➡ 被所有",
+    "relations.coi.label" => "包含[全集] ➡ 被包含[子集]元素/集合 ➡ 个体元素",
+    "relations.lov.label" => "容器 ➡ 动词/容纳 ➡ 被容纳",
+    "relations.mot.label" => "表现 ➡ 有表现",
+    "relations.whp.label" => "整体 ➡ 局部",
+    "relations.def.label" => "特征限定",
+    "relations.ac.label" => "绝对从句",
+    "relations.avc.label" => "绝对语态从句",
+    "relations.qus.label" => "引号内 ➡ 引号",
+    "relations.qum.label" => "引号 ➡ 引号外",
+    "relations.enu.label" => "罗列 ➡ 破折号",
+    "relations.enm.label" => "破折号 ➡ 被罗列",
+];

+ 4 - 0
api-v12/resources/lang/zh-Hans/label.php

@@ -0,0 +1,4 @@
+<?php
+return [
+    'translation' => '译文',
+];

+ 5 - 0
api-v12/resources/lang/zh-Hans/labels.php

@@ -0,0 +1,5 @@
+<?php
+return [
+    'home' => '首页',
+    'translation' => '译文',
+];

+ 19 - 0
api-v12/resources/lang/zh-Hans/pagination.php

@@ -0,0 +1,19 @@
+<?php
+
+return [
+
+    /*
+    |--------------------------------------------------------------------------
+    | Pagination Language Lines
+    |--------------------------------------------------------------------------
+    |
+    | The following language lines are used by the paginator library to build
+    | the simple pagination links. You are free to change them to anything
+    | you want to customize your views to better match your application.
+    |
+    */
+
+    'previous' => '&laquo; Previous',
+    'next' => 'Next &raquo;',
+
+];

+ 22 - 0
api-v12/resources/lang/zh-Hans/passwords.php

@@ -0,0 +1,22 @@
+<?php
+
+return [
+
+    /*
+    |--------------------------------------------------------------------------
+    | Password Reset Language Lines
+    |--------------------------------------------------------------------------
+    |
+    | The following language lines are the default lines which match reasons
+    | that are given by the password broker for a password update attempt
+    | has failed, such as for an invalid token or invalid new password.
+    |
+    */
+
+    'reset' => 'Your password has been reset!',
+    'sent' => 'We have emailed your password reset link!',
+    'throttled' => 'Please wait before retrying.',
+    'token' => 'This password reset token is invalid.',
+    'user' => "We can't find a user with that email address.",
+
+];

+ 22 - 0
api-v12/resources/lang/zh-Hans/site.php

@@ -0,0 +1,22 @@
+<?php
+
+return [
+
+    /*
+    |--------------------------------------------------------------------------
+    | site Language Lines
+    |--------------------------------------------------------------------------
+    |
+    |
+    */
+
+    'logo' => '/logo.png',
+    'title' => '维基巴利',
+    'subhead' => 'wikipali',
+    'keywords' => ['巴利语','佛教'],
+    'description' => 'wikipali',
+    'copyright' => 'iapt 2022',
+    'author.name' => 'iapt',
+    'author.email' => 'visuddhindand@gmail.com',
+
+];

+ 162 - 0
api-v12/resources/lang/zh-Hans/validation.php

@@ -0,0 +1,162 @@
+<?php
+
+return [
+
+    /*
+    |--------------------------------------------------------------------------
+    | Validation Language Lines
+    |--------------------------------------------------------------------------
+    |
+    | The following language lines contain the default error messages used by
+    | the validator class. Some of these rules have multiple versions such
+    | as the size rules. Feel free to tweak each of these messages here.
+    |
+    */
+
+    'accepted' => 'The :attribute must be accepted.',
+    'accepted_if' => 'The :attribute must be accepted when :other is :value.',
+    'active_url' => 'The :attribute is not a valid URL.',
+    'after' => 'The :attribute must be a date after :date.',
+    'after_or_equal' => 'The :attribute must be a date after or equal to :date.',
+    'alpha' => 'The :attribute must only contain letters.',
+    'alpha_dash' => 'The :attribute must only contain letters, numbers, dashes and underscores.',
+    'alpha_num' => 'The :attribute must only contain letters and numbers.',
+    'array' => 'The :attribute must be an array.',
+    'before' => 'The :attribute must be a date before :date.',
+    'before_or_equal' => 'The :attribute must be a date before or equal to :date.',
+    'between' => [
+        'numeric' => 'The :attribute must be between :min and :max.',
+        'file' => 'The :attribute must be between :min and :max kilobytes.',
+        'string' => 'The :attribute must be between :min and :max characters.',
+        'array' => 'The :attribute must have between :min and :max items.',
+    ],
+    'boolean' => 'The :attribute field must be true or false.',
+    'confirmed' => 'The :attribute confirmation does not match.',
+    'current_password' => 'The password is incorrect.',
+    'date' => 'The :attribute is not a valid date.',
+    'date_equals' => 'The :attribute must be a date equal to :date.',
+    'date_format' => 'The :attribute does not match the format :format.',
+    'declined' => 'The :attribute must be declined.',
+    'declined_if' => 'The :attribute must be declined when :other is :value.',
+    'different' => 'The :attribute and :other must be different.',
+    'digits' => 'The :attribute must be :digits digits.',
+    'digits_between' => 'The :attribute must be between :min and :max digits.',
+    'dimensions' => 'The :attribute has invalid image dimensions.',
+    'distinct' => 'The :attribute field has a duplicate value.',
+    'email' => 'The :attribute must be a valid email address.',
+    'ends_with' => 'The :attribute must end with one of the following: :values.',
+    'enum' => 'The selected :attribute is invalid.',
+    'exists' => 'The selected :attribute is invalid.',
+    'file' => 'The :attribute must be a file.',
+    'filled' => 'The :attribute field must have a value.',
+    'gt' => [
+        'numeric' => 'The :attribute must be greater than :value.',
+        'file' => 'The :attribute must be greater than :value kilobytes.',
+        'string' => 'The :attribute must be greater than :value characters.',
+        'array' => 'The :attribute must have more than :value items.',
+    ],
+    'gte' => [
+        'numeric' => 'The :attribute must be greater than or equal to :value.',
+        'file' => 'The :attribute must be greater than or equal to :value kilobytes.',
+        'string' => 'The :attribute must be greater than or equal to :value characters.',
+        'array' => 'The :attribute must have :value items or more.',
+    ],
+    'image' => 'The :attribute must be an image.',
+    'in' => 'The selected :attribute is invalid.',
+    'in_array' => 'The :attribute field does not exist in :other.',
+    'integer' => 'The :attribute must be an integer.',
+    'ip' => 'The :attribute must be a valid IP address.',
+    'ipv4' => 'The :attribute must be a valid IPv4 address.',
+    'ipv6' => 'The :attribute must be a valid IPv6 address.',
+    'mac_address' => 'The :attribute must be a valid MAC address.',
+    'json' => 'The :attribute must be a valid JSON string.',
+    'lt' => [
+        'numeric' => 'The :attribute must be less than :value.',
+        'file' => 'The :attribute must be less than :value kilobytes.',
+        'string' => 'The :attribute must be less than :value characters.',
+        'array' => 'The :attribute must have less than :value items.',
+    ],
+    'lte' => [
+        'numeric' => 'The :attribute must be less than or equal to :value.',
+        'file' => 'The :attribute must be less than or equal to :value kilobytes.',
+        'string' => 'The :attribute must be less than or equal to :value characters.',
+        'array' => 'The :attribute must not have more than :value items.',
+    ],
+    'max' => [
+        'numeric' => 'The :attribute must not be greater than :max.',
+        'file' => 'The :attribute must not be greater than :max kilobytes.',
+        'string' => 'The :attribute must not be greater than :max characters.',
+        'array' => 'The :attribute must not have more than :max items.',
+    ],
+    'mimes' => 'The :attribute must be a file of type: :values.',
+    'mimetypes' => 'The :attribute must be a file of type: :values.',
+    'min' => [
+        'numeric' => 'The :attribute must be at least :min.',
+        'file' => 'The :attribute must be at least :min kilobytes.',
+        'string' => 'The :attribute must be at least :min characters.',
+        'array' => 'The :attribute must have at least :min items.',
+    ],
+    'multiple_of' => 'The :attribute must be a multiple of :value.',
+    'not_in' => 'The selected :attribute is invalid.',
+    'not_regex' => 'The :attribute format is invalid.',
+    'numeric' => 'The :attribute must be a number.',
+    'password' => 'The password is incorrect.',
+    'present' => 'The :attribute field must be present.',
+    'prohibited' => 'The :attribute field is prohibited.',
+    'prohibited_if' => 'The :attribute field is prohibited when :other is :value.',
+    'prohibited_unless' => 'The :attribute field is prohibited unless :other is in :values.',
+    'prohibits' => 'The :attribute field prohibits :other from being present.',
+    'regex' => 'The :attribute format is invalid.',
+    'required' => 'The :attribute field is required.',
+    'required_if' => 'The :attribute field is required when :other is :value.',
+    'required_unless' => 'The :attribute field is required unless :other is in :values.',
+    'required_with' => 'The :attribute field is required when :values is present.',
+    'required_with_all' => 'The :attribute field is required when :values are present.',
+    'required_without' => 'The :attribute field is required when :values is not present.',
+    'required_without_all' => 'The :attribute field is required when none of :values are present.',
+    'same' => 'The :attribute and :other must match.',
+    'size' => [
+        'numeric' => 'The :attribute must be :size.',
+        'file' => 'The :attribute must be :size kilobytes.',
+        'string' => 'The :attribute must be :size characters.',
+        'array' => 'The :attribute must contain :size items.',
+    ],
+    'starts_with' => 'The :attribute must start with one of the following: :values.',
+    'string' => 'The :attribute must be a string.',
+    'timezone' => 'The :attribute must be a valid timezone.',
+    'unique' => 'The :attribute has already been taken.',
+    'uploaded' => 'The :attribute failed to upload.',
+    'url' => 'The :attribute must be a valid URL.',
+    'uuid' => 'The :attribute must be a valid UUID.',
+
+    /*
+    |--------------------------------------------------------------------------
+    | Custom Validation Language Lines
+    |--------------------------------------------------------------------------
+    |
+    | Here you may specify custom validation messages for attributes using the
+    | convention "attribute.rule" to name the lines. This makes it quick to
+    | specify a specific custom language line for a given attribute rule.
+    |
+    */
+
+    'custom' => [
+        'attribute-name' => [
+            'rule-name' => 'custom-message',
+        ],
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | Custom Validation Attributes
+    |--------------------------------------------------------------------------
+    |
+    | The following language lines are used to swap our attribute placeholder
+    | with something more reader friendly such as "E-Mail Address" instead
+    | of "email". This simply helps us make our message more expressive.
+    |
+    */
+
+    'attributes' => [],
+
+];

+ 20 - 0
api-v12/resources/lang/zh-Hant/auth.php

@@ -0,0 +1,20 @@
+<?php
+
+return [
+
+    /*
+    |--------------------------------------------------------------------------
+    | Authentication Language Lines
+    |--------------------------------------------------------------------------
+    |
+    | The following language lines are used during authentication for various
+    | messages that we need to display to the user. You are free to modify
+    | these language lines according to your application's requirements.
+    |
+    */
+
+    'failed' => 'These credentials do not match our records.',
+    'password' => 'The provided password is incorrect.',
+    'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
+
+];

+ 5 - 0
api-v12/resources/lang/zh-Hant/buttons.php

@@ -0,0 +1,5 @@
+<?php
+return [
+    'more' => '更多',
+    'online-read' =>  '在线阅读',
+];

+ 5 - 0
api-v12/resources/lang/zh-Hant/labels.php

@@ -0,0 +1,5 @@
+<?php
+return [
+    'home' => '首页',
+    'translation' => '译文',
+];

+ 19 - 0
api-v12/resources/lang/zh-Hant/pagination.php

@@ -0,0 +1,19 @@
+<?php
+
+return [
+
+    /*
+    |--------------------------------------------------------------------------
+    | Pagination Language Lines
+    |--------------------------------------------------------------------------
+    |
+    | The following language lines are used by the paginator library to build
+    | the simple pagination links. You are free to change them to anything
+    | you want to customize your views to better match your application.
+    |
+    */
+
+    'previous' => '&laquo; Previous',
+    'next' => 'Next &raquo;',
+
+];

+ 22 - 0
api-v12/resources/lang/zh-Hant/passwords.php

@@ -0,0 +1,22 @@
+<?php
+
+return [
+
+    /*
+    |--------------------------------------------------------------------------
+    | Password Reset Language Lines
+    |--------------------------------------------------------------------------
+    |
+    | The following language lines are the default lines which match reasons
+    | that are given by the password broker for a password update attempt
+    | has failed, such as for an invalid token or invalid new password.
+    |
+    */
+
+    'reset' => 'Your password has been reset!',
+    'sent' => 'We have emailed your password reset link!',
+    'throttled' => 'Please wait before retrying.',
+    'token' => 'This password reset token is invalid.',
+    'user' => "We can't find a user with that email address.",
+
+];

+ 22 - 0
api-v12/resources/lang/zh-Hant/site.php

@@ -0,0 +1,22 @@
+<?php
+
+return [
+
+    /*
+    |--------------------------------------------------------------------------
+    | site Language Lines
+    |--------------------------------------------------------------------------
+    |
+    |
+    */
+
+    'logo' => '/logo.png',
+    'title' => '维基巴利',
+    'subhead' => 'wikipali',
+    'keywords' => ['巴利语','佛教'],
+    'description' => 'wikipali',
+    'copyright' => 'iapt 2022',
+    'author.name' => 'iapt',
+    'author.email' => 'visuddhindand@gmail.com',
+
+];

+ 162 - 0
api-v12/resources/lang/zh-Hant/validation.php

@@ -0,0 +1,162 @@
+<?php
+
+return [
+
+    /*
+    |--------------------------------------------------------------------------
+    | Validation Language Lines
+    |--------------------------------------------------------------------------
+    |
+    | The following language lines contain the default error messages used by
+    | the validator class. Some of these rules have multiple versions such
+    | as the size rules. Feel free to tweak each of these messages here.
+    |
+    */
+
+    'accepted' => 'The :attribute must be accepted.',
+    'accepted_if' => 'The :attribute must be accepted when :other is :value.',
+    'active_url' => 'The :attribute is not a valid URL.',
+    'after' => 'The :attribute must be a date after :date.',
+    'after_or_equal' => 'The :attribute must be a date after or equal to :date.',
+    'alpha' => 'The :attribute must only contain letters.',
+    'alpha_dash' => 'The :attribute must only contain letters, numbers, dashes and underscores.',
+    'alpha_num' => 'The :attribute must only contain letters and numbers.',
+    'array' => 'The :attribute must be an array.',
+    'before' => 'The :attribute must be a date before :date.',
+    'before_or_equal' => 'The :attribute must be a date before or equal to :date.',
+    'between' => [
+        'numeric' => 'The :attribute must be between :min and :max.',
+        'file' => 'The :attribute must be between :min and :max kilobytes.',
+        'string' => 'The :attribute must be between :min and :max characters.',
+        'array' => 'The :attribute must have between :min and :max items.',
+    ],
+    'boolean' => 'The :attribute field must be true or false.',
+    'confirmed' => 'The :attribute confirmation does not match.',
+    'current_password' => 'The password is incorrect.',
+    'date' => 'The :attribute is not a valid date.',
+    'date_equals' => 'The :attribute must be a date equal to :date.',
+    'date_format' => 'The :attribute does not match the format :format.',
+    'declined' => 'The :attribute must be declined.',
+    'declined_if' => 'The :attribute must be declined when :other is :value.',
+    'different' => 'The :attribute and :other must be different.',
+    'digits' => 'The :attribute must be :digits digits.',
+    'digits_between' => 'The :attribute must be between :min and :max digits.',
+    'dimensions' => 'The :attribute has invalid image dimensions.',
+    'distinct' => 'The :attribute field has a duplicate value.',
+    'email' => 'The :attribute must be a valid email address.',
+    'ends_with' => 'The :attribute must end with one of the following: :values.',
+    'enum' => 'The selected :attribute is invalid.',
+    'exists' => 'The selected :attribute is invalid.',
+    'file' => 'The :attribute must be a file.',
+    'filled' => 'The :attribute field must have a value.',
+    'gt' => [
+        'numeric' => 'The :attribute must be greater than :value.',
+        'file' => 'The :attribute must be greater than :value kilobytes.',
+        'string' => 'The :attribute must be greater than :value characters.',
+        'array' => 'The :attribute must have more than :value items.',
+    ],
+    'gte' => [
+        'numeric' => 'The :attribute must be greater than or equal to :value.',
+        'file' => 'The :attribute must be greater than or equal to :value kilobytes.',
+        'string' => 'The :attribute must be greater than or equal to :value characters.',
+        'array' => 'The :attribute must have :value items or more.',
+    ],
+    'image' => 'The :attribute must be an image.',
+    'in' => 'The selected :attribute is invalid.',
+    'in_array' => 'The :attribute field does not exist in :other.',
+    'integer' => 'The :attribute must be an integer.',
+    'ip' => 'The :attribute must be a valid IP address.',
+    'ipv4' => 'The :attribute must be a valid IPv4 address.',
+    'ipv6' => 'The :attribute must be a valid IPv6 address.',
+    'mac_address' => 'The :attribute must be a valid MAC address.',
+    'json' => 'The :attribute must be a valid JSON string.',
+    'lt' => [
+        'numeric' => 'The :attribute must be less than :value.',
+        'file' => 'The :attribute must be less than :value kilobytes.',
+        'string' => 'The :attribute must be less than :value characters.',
+        'array' => 'The :attribute must have less than :value items.',
+    ],
+    'lte' => [
+        'numeric' => 'The :attribute must be less than or equal to :value.',
+        'file' => 'The :attribute must be less than or equal to :value kilobytes.',
+        'string' => 'The :attribute must be less than or equal to :value characters.',
+        'array' => 'The :attribute must not have more than :value items.',
+    ],
+    'max' => [
+        'numeric' => 'The :attribute must not be greater than :max.',
+        'file' => 'The :attribute must not be greater than :max kilobytes.',
+        'string' => 'The :attribute must not be greater than :max characters.',
+        'array' => 'The :attribute must not have more than :max items.',
+    ],
+    'mimes' => 'The :attribute must be a file of type: :values.',
+    'mimetypes' => 'The :attribute must be a file of type: :values.',
+    'min' => [
+        'numeric' => 'The :attribute must be at least :min.',
+        'file' => 'The :attribute must be at least :min kilobytes.',
+        'string' => 'The :attribute must be at least :min characters.',
+        'array' => 'The :attribute must have at least :min items.',
+    ],
+    'multiple_of' => 'The :attribute must be a multiple of :value.',
+    'not_in' => 'The selected :attribute is invalid.',
+    'not_regex' => 'The :attribute format is invalid.',
+    'numeric' => 'The :attribute must be a number.',
+    'password' => 'The password is incorrect.',
+    'present' => 'The :attribute field must be present.',
+    'prohibited' => 'The :attribute field is prohibited.',
+    'prohibited_if' => 'The :attribute field is prohibited when :other is :value.',
+    'prohibited_unless' => 'The :attribute field is prohibited unless :other is in :values.',
+    'prohibits' => 'The :attribute field prohibits :other from being present.',
+    'regex' => 'The :attribute format is invalid.',
+    'required' => 'The :attribute field is required.',
+    'required_if' => 'The :attribute field is required when :other is :value.',
+    'required_unless' => 'The :attribute field is required unless :other is in :values.',
+    'required_with' => 'The :attribute field is required when :values is present.',
+    'required_with_all' => 'The :attribute field is required when :values are present.',
+    'required_without' => 'The :attribute field is required when :values is not present.',
+    'required_without_all' => 'The :attribute field is required when none of :values are present.',
+    'same' => 'The :attribute and :other must match.',
+    'size' => [
+        'numeric' => 'The :attribute must be :size.',
+        'file' => 'The :attribute must be :size kilobytes.',
+        'string' => 'The :attribute must be :size characters.',
+        'array' => 'The :attribute must contain :size items.',
+    ],
+    'starts_with' => 'The :attribute must start with one of the following: :values.',
+    'string' => 'The :attribute must be a string.',
+    'timezone' => 'The :attribute must be a valid timezone.',
+    'unique' => 'The :attribute has already been taken.',
+    'uploaded' => 'The :attribute failed to upload.',
+    'url' => 'The :attribute must be a valid URL.',
+    'uuid' => 'The :attribute must be a valid UUID.',
+
+    /*
+    |--------------------------------------------------------------------------
+    | Custom Validation Language Lines
+    |--------------------------------------------------------------------------
+    |
+    | Here you may specify custom validation messages for attributes using the
+    | convention "attribute.rule" to name the lines. This makes it quick to
+    | specify a specific custom language line for a given attribute rule.
+    |
+    */
+
+    'custom' => [
+        'attribute-name' => [
+            'rule-name' => 'custom-message',
+        ],
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | Custom Validation Attributes
+    |--------------------------------------------------------------------------
+    |
+    | The following language lines are used to swap our attribute placeholder
+    | with something more reader friendly such as "E-Mail Address" instead
+    | of "email". This simply helps us make our message more expressive.
+    |
+    */
+
+    'attributes' => [],
+
+];

+ 6 - 0
api-v12/resources/mustache/article/html/footnote.html

@@ -0,0 +1,6 @@
+<h2 id="footnote">脚注</h2>
+<div class="footnote">
+[[#footnote]]
+<div class="item" id="footnote-[[sn]]"><a href="#note-[[sn]]" name="footnote-[[sn]]">[[sn]]</a>[[trigger]]:[[content]]</div>
+[[/footnote]]
+</div>

+ 9 - 0
api-v12/resources/mustache/article/html/glossary.html

@@ -0,0 +1,9 @@
+<h2>glossary</h2>
+<div class="glossary">
+[[#pali]]
+<div class="item pali"><span class="head">[[pali]]</span><span class="content">[[meaning]]</span></div>
+[[/pali]]
+[[#meaning]]
+<div class="item meaning"><span class="head">[[meaning]]</span><span  class="content">[[pali]]</span></div>
+[[/meaning]]
+</div>

+ 87 - 0
api-v12/resources/mustache/article/html/main.html

@@ -0,0 +1,87 @@
+<html lang="en-us">
+  <head>
+    <meta charset="utf-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
+    <title>[[book_title]]</title>
+    <style>
+        p {
+            text-indent: 2em;
+            line-height: 1.7em;
+        }
+        .sentence>p{
+            display: inline;
+        }
+        a {
+            text-decoration: none;
+        }
+        .paragraph {
+            margin-bottom: 1em;
+        }
+
+        .row {
+            display: flex;
+        }
+        img{
+            max-width: 100%;
+        }
+        @media screen and (max-width: 960px){
+            .row {
+                flex-direction: column;
+            }
+        }
+        .col {
+            flex: 5;
+        }
+        code {
+            background-color: #ffe4c478;
+            padding: 2px 6px;
+            border-radius: 4px;
+        }
+        .origin {
+            font-family: times;
+        }
+
+        table {
+            border-spacing: 0;
+            border-collapse: collapse;
+            display: block;
+            width: -webkit-max-content;
+            width: max-content;
+            max-width: 100%;
+        }
+
+        td,
+        th {
+            padding: 0;
+        }
+
+        table th {
+            font-weight: 600;
+        }
+
+        table th,
+        table td {
+            padding: 6px 13px;
+            border: 1px solid black;
+        }
+
+        table tr {
+            background-color: #ffffff;
+            border-top: 1px solid hsl(210, 18%, 87%);
+        }
+
+        table img {
+            background-color: transparent;
+        }
+    </style>
+</head>
+<body>
+<h1>[[book_title]]</h1>
+
+<h2>目录</h2>
+<ul>
+    [[#sections]]
+    <li><a href="#[[filename]]">[[filename]]</a></li>
+    [[/sections]]
+</ul>
+

+ 5 - 0
api-v12/resources/mustache/article/html/section.html

@@ -0,0 +1,5 @@
+[[#articles]]
+<h[[level]]>[[title]]</h[[level]]>
+[[#subtitle]]<div class="subtitle">[[subtitle]]</div>[[/subtitle]]
+<div class="content">[[content]]</div>
+[[/articles]]

+ 3 - 0
api-v12/resources/mustache/article/md/footnote.md

@@ -0,0 +1,3 @@
+[[#footnote]]
+\[[[sn]]\]: [[content]]
+[[/footnote]]

+ 9 - 0
api-v12/resources/mustache/article/md/glossary.md

@@ -0,0 +1,9 @@
+# glossary
+<div class="glossary">
+[[#pali]]
+<div class="item pali"><span class="head">[[pali]]</span><span class="content">[[meaning]]</span></div>
+[[/pali]]
+[[#meaning]]
+<div class="item meaning"><span class="head">[[meaning]]</span><span  class="content">[[pali]]</span></div>
+[[/meaning]]
+</div>

+ 3 - 0
api-v12/resources/mustache/article/md/main.md

@@ -0,0 +1,3 @@
+# [[book_title]]
+
+

+ 8 - 0
api-v12/resources/mustache/article/md/section.md

@@ -0,0 +1,8 @@
+[[#articles]]
+<h[[level]]>[[title]]</h[[level]]>
+
+[[#subtitle]][[subtitle]][[/subtitle]]
+
+[[content]]
+
+[[/articles]]

+ 6 - 0
api-v12/resources/mustache/chapter/html/footnote.html

@@ -0,0 +1,6 @@
+<h2 id="footnote">脚注</h2>
+<div class="footnote">
+[[#footnote]]
+<div class="item" id="footnote-[[sn]]"><a href="#note-[[sn]]" name="footnote-[[sn]]">[[sn]]</a>[[trigger]]:[[content]]</div>
+[[/footnote]]
+</div>

+ 15 - 0
api-v12/resources/mustache/chapter/html/glossary.html

@@ -0,0 +1,15 @@
+<h2>glossary</h2>
+<div class="glossary">
+<h3>Sort by Pali</h3>
+<table>
+[[#pali]]
+<tr class="item pali"><td class="head">[[pali]]</td><td class="content">[[meaning]]</td></tr>
+[[/pali]]
+</table>
+<h3>Sort by Translation</h3>
+<table>
+[[#meaning]]
+<tr class="item meaning"><td class="head">[[meaning]]</td><td  class="content">[[pali]]</td></tr>
+[[/meaning]]
+</table>
+</div>

+ 51 - 0
api-v12/resources/mustache/chapter/html/main.html

@@ -0,0 +1,51 @@
+<html lang="en-us">
+  <head>
+    <meta charset="utf-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
+    <title>[[book_title]]</title>
+    <style>
+        p {
+            text-indent: 2em;
+            line-height: 1.7em;
+        }
+        a {
+            text-decoration: none;
+        }
+        .paragraph {
+            margin-bottom: 1em;
+        }
+
+        .row {
+            display: flex;
+        }
+        @media screen and (max-width: 960px){
+            .row {
+                flex-direction: column;
+            }
+        }
+        .col {
+            flex: 5;
+        }
+        code {
+            background-color: #ffe4c478;
+            padding: 2px 6px;
+            border-radius: 4px;
+        }
+        .origin {
+            font-family: times;
+        }
+        .col p{
+            display:inline;
+        }
+    </style>
+</head>
+<body>
+<h1>[[book_title]]</h1>
+
+<h2>目录</h2>
+<ul>
+    [[#sections]]
+    <li><a href="#[[filename]]">[[filename]]</a></li>
+    [[/sections]]
+</ul>
+

+ 6 - 0
api-v12/resources/mustache/chapter/html/paragraph.html

@@ -0,0 +1,6 @@
+<div class="paragraph row [[layout]]">
+    [[#origin]]<div class="col origin">[[origin]]</div>[[/origin]]
+    [[#translations]]
+    <div class="col translation">[[content]]</div>
+    [[/translations]]
+</div>

+ 3 - 0
api-v12/resources/mustache/chapter/html/section.html

@@ -0,0 +1,3 @@
+<h2 id="[[title]]">[[title]]</h2>
+[[content]]
+

+ 6 - 0
api-v12/resources/mustache/chapter/html/sentence.html

@@ -0,0 +1,6 @@
+<div class="row [[layout]]">
+    <div class="col origin">[[origin]]</div>
+    [[#translations]]
+    <div class="col translation">[[content]]</div>
+    [[/translations]]
+</div>

+ 3 - 0
api-v12/resources/mustache/chapter/md/footnote.md

@@ -0,0 +1,3 @@
+[[#footnote]]
+\[[[sn]]\]: [[content]]
+[[/footnote]]

+ 15 - 0
api-v12/resources/mustache/chapter/md/glossary.md

@@ -0,0 +1,15 @@
+<h2>glossary</h2>
+<div class="glossary">
+<h3>Sort by Pali</h3>
+<table>
+[[#pali]]
+<tr class="item pali"><td class="head">[[pali]]</td><td class="content">[[meaning]]</td></tr>
+[[/pali]]
+</table>
+<h3>Sort by Translation</h3>
+<table>
+[[#meaning]]
+<tr class="item meaning"><td class="head">[[meaning]]</td><td  class="content">[[pali]]</td></tr>
+[[/meaning]]
+</table>
+</div>

+ 3 - 0
api-v12/resources/mustache/chapter/md/main.md

@@ -0,0 +1,3 @@
+# [[book_title]]
+
+

+ 8 - 0
api-v12/resources/mustache/chapter/md/paragraph.md

@@ -0,0 +1,8 @@
+[[#origin]]
+[[origin]]
+[[/origin]]
+[[#translations]]
+[[content]]
+[[/translations]]
+
+

+ 4 - 0
api-v12/resources/mustache/chapter/md/section.md

@@ -0,0 +1,4 @@
+## [[title]]
+
+[[content]]
+

+ 7 - 0
api-v12/resources/mustache/chapter/md/sentence.md

@@ -0,0 +1,7 @@
+[[origin]]
+
+[[#translations]]
+[[content]]
+
+[[/translations]]
+

+ 20 - 0
api-v12/resources/mustache/chapter/tex/main.tex

@@ -0,0 +1,20 @@
+% 导言区
+\documentclass[a4paper, 12pt, fontset=ubuntu]{article} % book, report, letter
+\usepackage{ctex} % Use chinese package
+
+\title{\heiti [[book_title]]}
+\author{\kaishu [[book_author]]}
+\date{\today}
+
+% 正文区
+
+\begin{document}
+    \maketitle % 头部信息在正文显示
+    \newpage
+    \tableofcontents % 显示索引列
+
+    [[#sections]]
+    \include{ [[filename]]}
+    [[/sections]]
+
+\end{document}

+ 6 - 0
api-v12/resources/mustache/chapter/tex/paragraph.tex

@@ -0,0 +1,6 @@
+\par [[origin]]
+
+[[#translations]]
+\par [[content]]
+[[/translations]]
+

+ 3 - 0
api-v12/resources/mustache/chapter/tex/section.tex

@@ -0,0 +1,3 @@
+\section{[[title]]}
+[[content]]
+

+ 5 - 0
api-v12/resources/mustache/chapter/tex/sentence.tex

@@ -0,0 +1,5 @@
+\newline [[origin]]</div>
+[[#translations]]
+\newline [[content]]
+[[/translations]]
+

+ 158 - 0
api-v12/resources/mustache/my_han_crop.tpl

@@ -0,0 +1,158 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <style type="text/css">
+            .img {
+                max-height: 27.5%;
+                /*max-width: 85%;*/
+                overflow-x: auto;
+                overflow-y: auto;
+                border-width: 1px 0 1px 0;
+                border-style: dashed;
+                border-color: transparent;
+                resize: vertical;
+                position: relative;
+            }
+
+            .img:hover {
+                border-color: black;
+            }
+            .dict {
+                width: 45vw;
+            }
+
+            .crop_a {
+                clip-path: inset(0 0 0 15%);
+                margin-left: -15%;
+            }
+            .crop_b {
+                clip-path: inset(0 15% 0 0);
+                margin-right: -15%;
+            }
+            .word {
+                width: 10vw;
+				display: contents;
+            }
+
+            .word-img img{
+                width: 35vw;
+                margin: -5px;
+            }
+			.result{
+				max-height: 200vw;
+			    overflow: scroll;
+			}
+            /* 默认滚动条样式 */
+            .img::-webkit-scrollbar {
+                width: 6px;
+                height: 6px;
+            }
+
+            .img::-webkit-scrollbar-track {
+                background: #f1f1f1;
+                border-radius: 6px;
+            }
+
+            .img:not(:hover)::-webkit-scrollbar-track {
+                background: transparent;
+            }
+
+            .img::-webkit-scrollbar-thumb {
+                background: #888;
+                border-radius: 6px;
+                transition: all 0.3s ease;
+            }
+
+            .img:not(:hover)::-webkit-scrollbar-thumb {
+                background: transparent;
+                border-radius: 6px;
+                transition: all 0.3s ease;
+            }
+
+            .img::-webkit-scrollbar-thumb:hover {
+                background: #555;
+            }
+            .result::-webkit-scrollbar {
+                width: 6px;
+                height: 6px;
+            }
+
+            .result::-webkit-scrollbar-track {
+                background: #f1f1f1;
+                border-radius: 6px;
+            }
+
+            .result:not(:hover)::-webkit-scrollbar-track {
+                background: transparent;
+            }
+
+            .result::-webkit-scrollbar-thumb {
+                background: #888;
+                border-radius: 6px;
+                transition: all 0.3s ease;
+            }
+
+            .result:not(:hover)::-webkit-scrollbar-thumb {
+                background: transparent;
+                border-radius: 6px;
+                transition: all 0.3s ease;
+            }
+
+            .result::-webkit-scrollbar-thumb:hover {
+                background: #555;
+            }
+            .copied {
+                color: #01955e;
+                display: none;
+                position: fixed;
+            }
+        </style>
+        <script>
+            function copy(text, index) {
+                navigator.clipboard.writeText(text).then(() => {
+                    show(index);
+                    setTimeout(() => {
+                        hide(index);
+                    }, 2000);
+                });
+            }
+            function show(index) {
+                let el = document.getElementById("copied-" + index);
+                el.style.display = "inline-block";
+            }
+            function hide(index) {
+                let el = document.getElementById("copied-" + index);
+                el.style.display = "none";
+            }
+        </script>
+    </head>
+    <body>
+        <h3>Page {{ page }}</h3>
+        <div style="display: flex">
+            <div>
+                {{#dict}}
+                <div class="img">
+                    <img class="dict crop_{{ index }}" src="{{ img }}" />
+                </div>
+                {{/dict}}
+            </div>
+            <div>
+                <table>
+                    {{#words}}
+                    <tr>
+                        <td class="word">{{ index }}</td>
+                        <td class="word">
+                            {{ word }}
+                            <button onclick="copy('{{ word }}',{{ index }})">复制</button>
+                            <span class="copied" id="copied-{{ index }}">已经复制</span>
+                        </td>
+                        <td class="word-img">
+                            <img src="img/{{ word }}.png" />
+                        </td>
+                    </tr>
+                    {{/words}}
+                </table>
+            </div>
+        </div>
+    </body>
+</html>

+ 11 - 0
api-v12/resources/mustache/nissaya_ending_card.tpl

@@ -0,0 +1,11 @@
+### {{ending}}-{{ending_tag}}
+
+**{{ending_meaning}}**
+
+{{ending_note}}
+
+|{{title_case}}|{{title_relation}}|{{title_local_link_to}}|{{title_content}}|{{title_local_ending}}|
+|-|-|-|-|-|
+{{#row}}
+|{{spell}}{{#case}}<a href='{{link}}' target='_blank'>{{label}}</a> {{/case}}|<a href='{{relation_link}}' target='_blank'>`{{relation}}`</a><br />{{local_relation}}|{{#to}}<a href='{{link}}' target='_blank'>`{{label}}`</a> {{/to}}|{{category_note}}|{{local_ending}}||
+{{/row}}

BIN
api-v12/resources/template/docx/paper.docx


+ 323 - 0
api-v12/resources/views/ananke.blade.php

@@ -0,0 +1,323 @@
+<html lang="en-us">
+  <head>
+    <meta charset="utf-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
+
+    <title>Ananke: a Hugo Theme | Ananke</title>
+    <meta name="viewport" content="width=device-width,minimum-scale=1" />
+    <meta
+      name="description"
+      content="The last theme you'll ever need. Maybe."
+    />
+    <meta name="generator" content="Hugo 0.92.1" />
+
+    <meta name="robots" content="noindex, nofollow" />
+
+    <link rel="stylesheet" href="{{ URL::asset('assets/css/ananke/main.min.css') }}" />
+
+    <link
+      href="/index.xml"
+      rel="alternate"
+      type="application/rss+xml"
+      title="Ananke"
+    />
+    <link
+      href="/index.xml"
+      rel="feed"
+      type="application/rss+xml"
+      title="Ananke"
+    />
+
+    <meta property="og:title" content="Ananke: a Hugo Theme" />
+    <meta
+      property="og:description"
+      content="The last theme you'll ever need. Maybe."
+    />
+    <meta property="og:type" content="website" />
+    <meta
+      property="og:url"
+      content="https://gohugo-ananke-theme-demo.netlify.app/"
+    />
+    <meta property="og:site_name" content="Ananke" />
+
+    <meta itemprop="name" content="Ananke: a Hugo Theme" />
+    <meta
+      itemprop="description"
+      content="The last theme you'll ever need. Maybe."
+    />
+    <meta name="twitter:card" content="summary" />
+    <meta name="twitter:title" content="Ananke: a Hugo Theme" />
+    <meta
+      name="twitter:description"
+      content="The last theme you'll ever need. Maybe."
+    />
+  </head>
+
+  <body
+    class="ma0 avenir bg-near-white"
+  >
+    <header
+      class="cover bg-top"
+      style="background-image: url('{{ URL::asset('assets/images/hero.jpg') }}');"
+    >
+      <div class="bg-black-60">
+        <nav class="pv3 ph3 ph4-ns" role="navigation">
+          <div class="flex-l justify-between items-center center">
+            <a href="/" class="f3 fw2 hover-white no-underline white-90 dib">
+              wikipali
+            </a>
+            <div class="flex-l items-center">
+              <h4></h4>
+              <ul class="pl0 mr3">
+                @foreach ($nav as $item)
+                <li class="list f5 f4-ns fw4 dib pr3">
+                  <a
+                    class="hover-white no-underline white-90"
+                    href="/pcd/{{ $item['link'] }}"
+                    title="{{ $item['title'] }}"
+                  >
+                    {{ $item['title'] }}
+                  </a>
+                </li>
+                @endforeach
+              </ul>
+
+            </div>
+          </div>
+        </nav>
+
+        <div class="tc-l pv4 pv6-l ph3 ph4-ns">
+          <h1 class="f2 f-subheadline-l fw2 white-90 mb0 lh-title">
+            {{ $title }}
+          </h1>
+
+          <h2 class="fw1 f5 f3-l white-80 measure-wide-l center mt3">
+          {{ $subtitle }}
+          </h2>
+        </div>
+      </div>
+    </header>
+
+    <main class="pb7" role="main">
+      <article
+        class="cf ph3 ph5-l pv3 pv4-l f4 tc-l center measure-wide lh-copy mid-gray"
+      >
+        <p>
+          Welcome to my blog with some of my work in progress. I’ve been working
+          on this book idea. You can read some of the chapters below.
+        </p>
+      </article>
+
+      <div class="pa3 pa4-ns w-100 w-70-ns center">
+        <section class="w-100 mw8">
+          <div class="relative w-100 mb4">
+            <article class="bb b--black-10">
+              <div class="db pv4 ph3 ph0-l no-underline dark-gray">
+                <div class="flex flex-column flex-row-ns">
+                  <div class="pr3-ns mb4 mb0-ns w-100 w-40-ns">
+                    <a href="/post/chapter-6/" class="db grow">
+                      <img
+                        src="https://gohugo-ananke-theme-demo.netlify.app/images/esmeralda.jpg"
+                        class="img"
+                        alt="image from Chapter VI: Esmeralda"
+                      />
+                    </a>
+                  </div>
+
+                  <div class="blah w-100 w-60-ns pl3-ns">
+                    <h1 class="f3 fw1 athelas mt0 lh-title">
+                      <a href="/post/chapter-6/" class="color-inherit dim link">
+                        Chapter VI: Esmeralda
+                      </a>
+                    </h1>
+                    <div
+                      class="f6 f5-l lh-copy nested-copy-line-height nested-links"
+                    >
+                      We are delighted to be able to inform the reader, that
+                      during the whole of this scene, Gringoire and his piece
+                      had stood firm. His actors, spurred on by him, had not
+                      ceased to spout his comedy, and he had not ceased to
+                      listen to it. He had made up his mind about the tumult,
+                      and was determined to proceed to the end, not giving up
+                      the hope of a return of attention on the part of the
+                      public.
+                    </div>
+                    <a
+                      href="/post/chapter-6/"
+                      class="ba b--moon-gray bg-light-gray br2 color-inherit dib f7 hover-bg-moon-gray link mt2 ph2 pv1"
+                      >read more</a
+                    >
+                  </div>
+                </div>
+              </div>
+            </article>
+          </div>
+
+          <div class="relative w-100 mb4">
+            <article class="bb b--black-10">
+              <div class="db pv4 ph3 ph0-l no-underline dark-gray">
+                <div class="flex flex-column flex-row-ns">
+                  <div class="blah w-100">
+                    <h1 class="f3 fw1 athelas mt0 lh-title">
+                      <a href="/post/chapter-5/" class="color-inherit dim link">
+                        Chapter V: Quasimodo
+                      </a>
+                    </h1>
+                    <div
+                      class="f6 f5-l lh-copy nested-copy-line-height nested-links"
+                    >
+                      In the twinkling of an eye, all was ready to execute
+                      Coppenole’s idea. Bourgeois, scholars and law clerks all
+                      set to work. The little chapel situated opposite the
+                      marble table was selected for the scene of the grinning
+                      match. A pane broken in the pretty rose window above the
+                      door, left free a circle of stone through which it was
+                      agreed that the competitors should thrust their heads. In
+                      order to reach it, it was only necessary to mount upon a
+                      couple of hogsheads, which had been produced from I know
+                      not where, and perched one upon the other, after a
+                      fashion.
+                    </div>
+                    <a
+                      href="/post/chapter-5/"
+                      class="ba b--moon-gray bg-light-gray br2 color-inherit dib f7 hover-bg-moon-gray link mt2 ph2 pv1"
+                      >read more</a
+                    >
+                  </div>
+                </div>
+              </div>
+            </article>
+          </div>
+
+          <div class="relative w-100 mb4">
+            <article class="bb b--black-10">
+              <div class="db pv4 ph3 ph0-l no-underline dark-gray">
+                <div class="flex flex-column flex-row-ns">
+                  <div class="blah w-100">
+                    <h1 class="f3 fw1 athelas mt0 lh-title">
+                      <a href="/post/chapter-4/" class="color-inherit dim link">
+                        Chapter IV: Master Jacques Coppenole
+                      </a>
+                    </h1>
+                    <div
+                      class="f6 f5-l lh-copy nested-copy-line-height nested-links"
+                    >
+                      While the pensioner of Ghent and his eminence were
+                      exchanging very low bows and a few words in voices still
+                      lower, a man of lofty stature, with a large face and broad
+                      shoulders, presented himself, in order to enter abreast
+                      with Guillaume Rym; one would have pronounced him a
+                      bull-dog by the side of a fox. His felt doublet and
+                      leather jerkin made a spot on the velvet and silk which
+                      surrounded him.
+                    </div>
+                    <a
+                      href="/post/chapter-4/"
+                      class="ba b--moon-gray bg-light-gray br2 color-inherit dib f7 hover-bg-moon-gray link mt2 ph2 pv1"
+                      >read more</a
+                    >
+                  </div>
+                </div>
+              </div>
+            </article>
+          </div>
+        </section>
+
+        <section class="w-100">
+          <h1 class="f3">More</h1>
+
+          <h2 class="f5 fw4 mb4 dib mr3">
+            <a href="/post/chapter-3/" class="link black dim">
+              Chapter III: Monsieur the Cardinal
+            </a>
+          </h2>
+
+          <h2 class="f5 fw4 mb4 dib mr3">
+            <a href="/post/chapter-2/" class="link black dim">
+              Chapter II: Pierre Gringoire
+            </a>
+          </h2>
+
+          <h2 class="f5 fw4 mb4 dib mr3">
+            <a href="/post/chapter-1/" class="link black dim">
+              Chapter I: The Grand Hall
+            </a>
+          </h2>
+
+          <a
+            href="/post/"
+            class="link db f6 pa2 br3 bg-mid-gray white dim w4 tc"
+            >All Articles</a
+          >
+        </section>
+      </div>
+    </main>
+    <footer class="bg-black bottom-0 w-100 pa3" role="contentinfo">
+      <div class="flex justify-between">
+        <a
+          class="f4 fw4 hover-white no-underline white-70 dn dib-ns pv2 ph3"
+          href="https://gohugo-ananke-theme-demo.netlify.app"
+        >
+          © Ananke 2022
+        </a>
+        <div>
+          <div class="ananke-socials">
+            <a
+              href="https://twitter.com/GoHugoIO"
+              target="_blank"
+              class="twitter ananke-social-link link-transition stackoverflow link dib z-999 pt3 pt0-l mr1"
+              title="Twitter link"
+              rel="noopener"
+              aria-label="follow on Twitter——Opens in a new window"
+            >
+              <span class="icon"
+                ><svg
+                  style="enable-background: new 0 0 67 67"
+                  version="1.1"
+                  viewBox="0 0 67 67"
+                  xml:space="preserve"
+                  xmlns="http://www.w3.org/2000/svg"
+                  xmlns:xlink="http://www.w3.org/1999/xlink"
+                >
+                  <path
+                    d="M37.167,22.283c-2.619,0.953-4.274,3.411-4.086,6.101  l0.063,1.038l-1.048-0.127c-3.813-0.487-7.145-2.139-9.974-4.915l-1.383-1.377l-0.356,1.017c-0.754,2.267-0.272,4.661,1.299,6.271  c0.838,0.89,0.649,1.017-0.796,0.487c-0.503-0.169-0.943-0.296-0.985-0.233c-0.146,0.149,0.356,2.076,0.754,2.839  c0.545,1.06,1.655,2.097,2.871,2.712l1.027,0.487l-1.215,0.021c-1.173,0-1.215,0.021-1.089,0.467  c0.419,1.377,2.074,2.839,3.918,3.475l1.299,0.444l-1.131,0.678c-1.676,0.976-3.646,1.526-5.616,1.568  C19.775,43.256,19,43.341,19,43.405c0,0.211,2.557,1.397,4.044,1.864c4.463,1.377,9.765,0.783,13.746-1.568  c2.829-1.673,5.657-5,6.978-8.221c0.713-1.716,1.425-4.851,1.425-6.354c0-0.975,0.063-1.102,1.236-2.267  c0.692-0.678,1.341-1.419,1.467-1.631c0.21-0.403,0.188-0.403-0.88-0.043c-1.781,0.636-2.033,0.551-1.152-0.402  c0.649-0.678,1.425-1.907,1.425-2.267c0-0.063-0.314,0.042-0.671,0.233c-0.377,0.212-1.215,0.53-1.844,0.72l-1.131,0.361l-1.027-0.7  c-0.566-0.381-1.361-0.805-1.781-0.932C39.766,21.902,38.131,21.944,37.167,22.283z M33,64C16.432,64,3,50.569,3,34S16.432,4,33,4  s30,13.431,30,30S49.568,64,33,64z"
+                    style="fill-rule: evenodd; clip-rule: evenodd"
+                  ></path>
+                </svg>
+              </span>
+
+              <span class="new-window"
+                ><svg
+                  height="8px"
+                  style="enable-background: new 0 0 1000 1000"
+                  version="1.1"
+                  viewBox="0 0 1000 1000"
+                  xml:space="preserve"
+                  xmlns="http://www.w3.org/2000/svg"
+                  xmlns:xlink="http://www.w3.org/1999/xlink"
+                >
+                  <path
+                    d="M598 128h298v298h-86v-152l-418 418-60-60 418-418h-152v-86zM810 810v-298h86v298c0 46-40 86-86 86h-596c-48 0-86-40-86-86v-596c0-46 38-86 86-86h298v86h-298v596h596z"
+                    style="fill-rule: evenodd; clip-rule: evenodd"
+                  ></path>
+                </svg> </span
+            ></a>
+          </div>
+        </div>
+      </div>
+    </footer>
+
+    <iframe
+      frameborder="0"
+      scrolling="no"
+      style="background-color: transparent; border: 0px; display: none"
+    ></iframe>
+    <div
+      id="GOOGLE_INPUT_CHEXT_FLAG"
+      input=""
+      input_stat='{"tlang":true,"tsbc":true,"pun":true,"mk":true,"ss":true}'
+      style="display: none"
+    ></div>
+    <div id="monica-content-root" class="monica-widget"></div>
+  </body>
+</html>

+ 56 - 0
api-v12/resources/views/blog/category.blade.php

@@ -0,0 +1,56 @@
+@extends('blog.layouts.app')
+
+@section('title', $user["nickName"])
+
+@section('content')
+
+<header>
+    <h3 class="section-title">Categories</h3>
+
+    <div class="section-card">
+        <div class="section-details">
+            <h3 class="section-count">{{ $count }} page</h3>
+            <h1 class="section-term">
+                @foreach ($current as $category)
+                /<a href="{{ route('blog.category', ['user' => $user['userName'],'category1' => $category['id'],]) }}">
+                    {{ $category['label'] }}
+                </a>
+                @endforeach
+            </h1>
+            <section class="widget tagCloud">
+                <div class="tagCloud-tags">
+                    @foreach($tagOptions as $id => $tag)
+                    @if($tag['count'] < $count)
+                        <a href="{{ rtrim(url()->current(), '/') . '/' . $tag['tag']->name }}">{{ $tag['tag']->name }}({{ $tag['count'] }})</a>
+                        @endif
+                        @endforeach
+                </div>
+            </section>
+        </div>
+    </div>
+</header>
+
+<section class="article-list--compact">
+    @foreach ($posts as $post)
+    <article>
+        <a href="{{ route('library.book.read', $post['uid']) }}">
+            <div class="article-details">
+                <h2 class="article-title">{{ $post->title }}</h2>
+                <footer class="article-time">
+                    <time datetime="2022-03-06T00:00:00Z">{{ $post->formatted_updated_at }}</time>
+                </footer>
+            </div>
+            <div class="article-image">
+                <img
+                    src="./Category_ Example Category - Hugo Theme Stack Starter_files/cover_hu6307248181568134095.jpg"
+                    width="120"
+                    height="120"
+                    alt="Hello World"
+                    loading="lazy" />
+            </div>
+        </a>
+    </article>
+    @endforeach
+</section>
+
+@endsection

+ 453 - 0
api-v12/resources/views/blog/index.blade.php

@@ -0,0 +1,453 @@
+@extends('blog.layouts.app')
+
+@section('title', $user["nickName"])
+
+@section('content')
+<section class="article-list">
+    @foreach ($posts as $post)
+    <article class="">
+        <header class="article-header">
+            <div class="article-details">
+                <header class="article-category">
+                    <a href="https://demo.stack.jimmycai.com/categories/themes/">
+                        Themes
+                    </a>
+
+                    <a href="https://demo.stack.jimmycai.com/categories/syntax/">
+                        Syntax
+                    </a>
+                </header>
+
+                <div class="article-title-wrapper">
+                    <h2 class="article-title">
+                        <a
+                            href="{{ route('library.book.read', $post['uid']) }}">{{ $post->title }}</a>
+                    </h2>
+
+                    <h3 class="article-subtitle">
+                        {{ $post->summary }}
+                    </h3>
+                </div>
+
+                <footer class="article-time">
+                    <div>
+                        <svg
+                            xmlns="http://www.w3.org/2000/svg"
+                            class="icon icon-tabler icon-tabler-calendar-time"
+                            width="56"
+                            height="56"
+                            viewBox="0 0 24 24"
+                            stroke-width="2"
+                            stroke="currentColor"
+                            fill="none"
+                            stroke-linecap="round"
+                            stroke-linejoin="round">
+                            <path stroke="none" d="M0 0h24v24H0z"></path>
+                            <path
+                                d="M11.795 21h-6.795a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v4"></path>
+                            <circle cx="18" cy="18" r="4"></circle>
+                            <path d="M15 3v4"></path>
+                            <path d="M7 3v4"></path>
+                            <path d="M3 11h16"></path>
+                            <path d="M18 16.496v1.504l1 1"></path>
+                        </svg>
+                        <time class="article-time--published">{{ $post->formatted_updated_at }}</time>
+                    </div>
+
+                    <div>
+                        <svg
+                            xmlns="http://www.w3.org/2000/svg"
+                            class="icon icon-tabler icon-tabler-clock"
+                            width="24"
+                            height="24"
+                            viewBox="0 0 24 24"
+                            stroke-width="2"
+                            stroke="currentColor"
+                            fill="none"
+                            stroke-linecap="round"
+                            stroke-linejoin="round">
+                            <path stroke="none" d="M0 0h24v24H0z"></path>
+                            <circle cx="12" cy="12" r="9"></circle>
+                            <polyline points="12 7 12 12 15 15"></polyline>
+                        </svg>
+
+                        <time class="article-time--reading"> 3 minute read </time>
+                    </div>
+                </footer>
+            </div>
+        </header>
+    </article>
+    @endforeach
+    <article class="has-image">
+        <header class="article-header">
+            <div class="article-image">
+                <a href="https://demo.stack.jimmycai.com/p/hello-world/">
+                    <img
+                        src="./Hugo Theme Stack Starter_files/cover_hu13459586684579990428.jpg"
+                        srcset="
+                      /p/hello-world/cover_hu13459586684579990428.jpg  800w,
+                      /p/hello-world/cover_hu3425483315149503896.jpg  1600w
+                    "
+                        width="800"
+                        height="534"
+                        loading="lazy"
+                        alt="Featured image of post Hello World" />
+                </a>
+            </div>
+
+            <div class="article-details">
+                <header class="article-category">
+                    <a
+                        href="https://demo.stack.jimmycai.com/categories/example-category/"
+                        style="background-color: #2a9d8f; color: #fff">
+                        Example Category
+                    </a>
+                </header>
+
+                <div class="article-title-wrapper">
+                    <h2 class="article-title">
+                        <a href="https://demo.stack.jimmycai.com/p/hello-world/">Hello World</a>
+                    </h2>
+
+                    <h3 class="article-subtitle">Welcome to Hugo Theme Stack</h3>
+                </div>
+
+                <footer class="article-time">
+                    <div>
+                        <svg
+                            xmlns="http://www.w3.org/2000/svg"
+                            class="icon icon-tabler icon-tabler-calendar-time"
+                            width="56"
+                            height="56"
+                            viewBox="0 0 24 24"
+                            stroke-width="2"
+                            stroke="currentColor"
+                            fill="none"
+                            stroke-linecap="round"
+                            stroke-linejoin="round">
+                            <path stroke="none" d="M0 0h24v24H0z"></path>
+                            <path
+                                d="M11.795 21h-6.795a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v4"></path>
+                            <circle cx="18" cy="18" r="4"></circle>
+                            <path d="M15 3v4"></path>
+                            <path d="M7 3v4"></path>
+                            <path d="M3 11h16"></path>
+                            <path d="M18 16.496v1.504l1 1"></path>
+                        </svg>
+                        <time class="article-time--published">Mar 06, 2022</time>
+                    </div>
+
+                    <div>
+                        <svg
+                            xmlns="http://www.w3.org/2000/svg"
+                            class="icon icon-tabler icon-tabler-clock"
+                            width="24"
+                            height="24"
+                            viewBox="0 0 24 24"
+                            stroke-width="2"
+                            stroke="currentColor"
+                            fill="none"
+                            stroke-linecap="round"
+                            stroke-linejoin="round">
+                            <path stroke="none" d="M0 0h24v24H0z"></path>
+                            <circle cx="12" cy="12" r="9"></circle>
+                            <polyline points="12 7 12 12 15 15"></polyline>
+                        </svg>
+
+                        <time class="article-time--reading"> 1 minute read </time>
+                    </div>
+                </footer>
+            </div>
+        </header>
+    </article>
+
+    <article class="">
+        <header class="article-header">
+            <div class="article-details">
+                <header class="article-category">
+                    <a href="https://demo.stack.jimmycai.com/categories/themes/">
+                        Themes
+                    </a>
+
+                    <a href="https://demo.stack.jimmycai.com/categories/syntax/">
+                        Syntax
+                    </a>
+                </header>
+
+                <div class="article-title-wrapper">
+                    <h2 class="article-title">
+                        <a
+                            href="https://demo.stack.jimmycai.com/p/markdown-syntax-guide/">Markdown Syntax Guide</a>
+                    </h2>
+
+                    <h3 class="article-subtitle">
+                        Sample article showcasing basic Markdown syntax and
+                        formatting for HTML elements.
+                    </h3>
+                </div>
+
+                <footer class="article-time">
+                    <div>
+                        <svg
+                            xmlns="http://www.w3.org/2000/svg"
+                            class="icon icon-tabler icon-tabler-calendar-time"
+                            width="56"
+                            height="56"
+                            viewBox="0 0 24 24"
+                            stroke-width="2"
+                            stroke="currentColor"
+                            fill="none"
+                            stroke-linecap="round"
+                            stroke-linejoin="round">
+                            <path stroke="none" d="M0 0h24v24H0z"></path>
+                            <path
+                                d="M11.795 21h-6.795a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v4"></path>
+                            <circle cx="18" cy="18" r="4"></circle>
+                            <path d="M15 3v4"></path>
+                            <path d="M7 3v4"></path>
+                            <path d="M3 11h16"></path>
+                            <path d="M18 16.496v1.504l1 1"></path>
+                        </svg>
+                        <time class="article-time--published">Sep 07, 2023</time>
+                    </div>
+
+                    <div>
+                        <svg
+                            xmlns="http://www.w3.org/2000/svg"
+                            class="icon icon-tabler icon-tabler-clock"
+                            width="24"
+                            height="24"
+                            viewBox="0 0 24 24"
+                            stroke-width="2"
+                            stroke="currentColor"
+                            fill="none"
+                            stroke-linecap="round"
+                            stroke-linejoin="round">
+                            <path stroke="none" d="M0 0h24v24H0z"></path>
+                            <circle cx="12" cy="12" r="9"></circle>
+                            <polyline points="12 7 12 12 15 15"></polyline>
+                        </svg>
+
+                        <time class="article-time--reading"> 3 minute read </time>
+                    </div>
+                </footer>
+            </div>
+        </header>
+    </article>
+
+    <article class="has-image">
+        <header class="article-header">
+            <div class="article-image">
+                <a href="https://demo.stack.jimmycai.com/p/image-gallery/">
+                    <img
+                        src="./Hugo Theme Stack Starter_files/2_hu3578945376017100738.jpg"
+                        srcset="
+                      /p/image-gallery/2_hu3578945376017100738.jpg  800w,
+                      /p/image-gallery/2_hu15750790370579438.jpg   1600w
+                    "
+                        width="800"
+                        height="1200"
+                        loading="lazy"
+                        alt="Featured image of post Image gallery" />
+                </a>
+            </div>
+
+            <div class="article-details">
+                <div class="article-title-wrapper">
+                    <h2 class="article-title">
+                        <a href="https://demo.stack.jimmycai.com/p/image-gallery/">Image gallery</a>
+                    </h2>
+
+                    <h3 class="article-subtitle">
+                        Create beautiful interactive image gallery using Markdown
+                    </h3>
+                </div>
+
+                <footer class="article-time">
+                    <div>
+                        <svg
+                            xmlns="http://www.w3.org/2000/svg"
+                            class="icon icon-tabler icon-tabler-calendar-time"
+                            width="56"
+                            height="56"
+                            viewBox="0 0 24 24"
+                            stroke-width="2"
+                            stroke="currentColor"
+                            fill="none"
+                            stroke-linecap="round"
+                            stroke-linejoin="round">
+                            <path stroke="none" d="M0 0h24v24H0z"></path>
+                            <path
+                                d="M11.795 21h-6.795a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v4"></path>
+                            <circle cx="18" cy="18" r="4"></circle>
+                            <path d="M15 3v4"></path>
+                            <path d="M7 3v4"></path>
+                            <path d="M3 11h16"></path>
+                            <path d="M18 16.496v1.504l1 1"></path>
+                        </svg>
+                        <time class="article-time--published">Aug 26, 2023</time>
+                    </div>
+
+                    <div>
+                        <svg
+                            xmlns="http://www.w3.org/2000/svg"
+                            class="icon icon-tabler icon-tabler-clock"
+                            width="24"
+                            height="24"
+                            viewBox="0 0 24 24"
+                            stroke-width="2"
+                            stroke="currentColor"
+                            fill="none"
+                            stroke-linecap="round"
+                            stroke-linejoin="round">
+                            <path stroke="none" d="M0 0h24v24H0z"></path>
+                            <circle cx="12" cy="12" r="9"></circle>
+                            <polyline points="12 7 12 12 15 15"></polyline>
+                        </svg>
+
+                        <time class="article-time--reading"> 1 minute read </time>
+                    </div>
+                </footer>
+            </div>
+        </header>
+    </article>
+
+    <article class="has-image">
+        <header class="article-header">
+            <div class="article-image">
+                <a href="https://demo.stack.jimmycai.com/p/shortcodes/">
+                    <img
+                        src="./Hugo Theme Stack Starter_files/cover_hu5876910065799140332.jpg"
+                        srcset="
+                      /p/shortcodes/cover_hu5876910065799140332.jpg   800w,
+                      /p/shortcodes/cover_hu14584859319700861491.jpg 1600w
+                    "
+                        width="800"
+                        height="533"
+                        loading="lazy"
+                        alt="Featured image of post Shortcodes" />
+                </a>
+            </div>
+
+            <div class="article-details">
+                <div class="article-title-wrapper">
+                    <h2 class="article-title">
+                        <a href="https://demo.stack.jimmycai.com/p/shortcodes/">Shortcodes</a>
+                    </h2>
+
+                    <h3 class="article-subtitle">
+                        Useful shortcodes that can be used in Markdown
+                    </h3>
+                </div>
+
+                <footer class="article-time">
+                    <div>
+                        <svg
+                            xmlns="http://www.w3.org/2000/svg"
+                            class="icon icon-tabler icon-tabler-calendar-time"
+                            width="56"
+                            height="56"
+                            viewBox="0 0 24 24"
+                            stroke-width="2"
+                            stroke="currentColor"
+                            fill="none"
+                            stroke-linecap="round"
+                            stroke-linejoin="round">
+                            <path stroke="none" d="M0 0h24v24H0z"></path>
+                            <path
+                                d="M11.795 21h-6.795a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v4"></path>
+                            <circle cx="18" cy="18" r="4"></circle>
+                            <path d="M15 3v4"></path>
+                            <path d="M7 3v4"></path>
+                            <path d="M3 11h16"></path>
+                            <path d="M18 16.496v1.504l1 1"></path>
+                        </svg>
+                        <time class="article-time--published">Aug 25, 2023</time>
+                    </div>
+
+                    <div>
+                        <svg
+                            xmlns="http://www.w3.org/2000/svg"
+                            class="icon icon-tabler icon-tabler-clock"
+                            width="24"
+                            height="24"
+                            viewBox="0 0 24 24"
+                            stroke-width="2"
+                            stroke="currentColor"
+                            fill="none"
+                            stroke-linecap="round"
+                            stroke-linejoin="round">
+                            <path stroke="none" d="M0 0h24v24H0z"></path>
+                            <circle cx="12" cy="12" r="9"></circle>
+                            <polyline points="12 7 12 12 15 15"></polyline>
+                        </svg>
+
+                        <time class="article-time--reading"> 1 minute read </time>
+                    </div>
+                </footer>
+            </div>
+        </header>
+    </article>
+
+    <article class="">
+        <header class="article-header">
+            <div class="article-details">
+                <div class="article-title-wrapper">
+                    <h2 class="article-title">
+                        <a
+                            href="https://demo.stack.jimmycai.com/p/math-typesetting/">Math Typesetting</a>
+                    </h2>
+
+                    <h3 class="article-subtitle">Math typesetting using KaTeX</h3>
+                </div>
+
+                <footer class="article-time">
+                    <div>
+                        <svg
+                            xmlns="http://www.w3.org/2000/svg"
+                            class="icon icon-tabler icon-tabler-calendar-time"
+                            width="56"
+                            height="56"
+                            viewBox="0 0 24 24"
+                            stroke-width="2"
+                            stroke="currentColor"
+                            fill="none"
+                            stroke-linecap="round"
+                            stroke-linejoin="round">
+                            <path stroke="none" d="M0 0h24v24H0z"></path>
+                            <path
+                                d="M11.795 21h-6.795a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v4"></path>
+                            <circle cx="18" cy="18" r="4"></circle>
+                            <path d="M15 3v4"></path>
+                            <path d="M7 3v4"></path>
+                            <path d="M3 11h16"></path>
+                            <path d="M18 16.496v1.504l1 1"></path>
+                        </svg>
+                        <time class="article-time--published">Aug 24, 2023</time>
+                    </div>
+
+                    <div>
+                        <svg
+                            xmlns="http://www.w3.org/2000/svg"
+                            class="icon icon-tabler icon-tabler-clock"
+                            width="24"
+                            height="24"
+                            viewBox="0 0 24 24"
+                            stroke-width="2"
+                            stroke="currentColor"
+                            fill="none"
+                            stroke-linecap="round"
+                            stroke-linejoin="round">
+                            <path stroke="none" d="M0 0h24v24H0z"></path>
+                            <circle cx="12" cy="12" r="9"></circle>
+                            <polyline points="12 7 12 12 15 15"></polyline>
+                        </svg>
+
+                        <time class="article-time--reading"> 1 minute read </time>
+                    </div>
+                </footer>
+            </div>
+        </header>
+    </article>
+</section>
+@endsection

+ 490 - 0
api-v12/resources/views/blog/layouts/app.blade.php

@@ -0,0 +1,490 @@
+<!DOCTYPE html>
+<!-- saved from url=(0032)https://demo.stack.jimmycai.com/ -->
+<html lang="en-us" dir="ltr" data-scheme="light">
+
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta name="generator" content="Hugo 0.134.1" />
+    <meta name="viewport" content="width=device-width, initial-scale=1" />
+    <meta
+        name="description"
+        content="Lorem ipsum dolor sit amet, consectetur adipiscing elit." />
+    <title></title>
+    <title>@yield('title', 'home')</title>
+    <link rel="canonical" href="https://demo.stack.jimmycai.com/" />
+
+    <link
+        rel="stylesheet"
+        href="{{ URL::asset('assets/css/blog/style.min.663803bebe609202d5b39d848f2d7c2dc8b598a2d879efa079fa88893d29c49c.css') }}" />
+    <meta property=" og:title" content="{{ $user["nickName"] }}" />
+    <meta
+        property="og:description"
+        content="Lorem ipsum dolor sit amet, consectetur adipiscing elit." />
+    <meta property="og:url" content="https://demo.stack.jimmycai.com/" />
+    <meta property="og:site_name" content="{{ $user["nickName"] }}" />
+    <meta property="og:type" content="website" />
+    <meta property="og:updated_time" content=" 2023-09-07T00:00:00+00:00 " />
+    <meta name="twitter:title" content="{{ $user["nickName"] }}" />
+    <meta
+        name="twitter:description"
+        content="Lorem ipsum dolor sit amet, consectetur adipiscing elit." />
+    <link
+        rel="alternate"
+        type="application/rss+xml"
+        href="https://demo.stack.jimmycai.com/index.xml" />
+    <link
+        rel="shortcut icon"
+        href="https://demo.stack.jimmycai.com/favicon.png" />
+    <link
+        href="{{ URL::asset('assets/css/blog/css2') }}"
+        type="text/css"
+        rel="stylesheet" />
+</head>
+
+<body
+    class=""
+    style="transition: background-color 0.3s">
+    <script>
+        (function() {
+            const colorSchemeKey = "StackColorScheme";
+            if (!localStorage.getItem(colorSchemeKey)) {
+                localStorage.setItem(colorSchemeKey, "auto");
+            }
+        })();
+    </script>
+    <script>
+        (function() {
+            const colorSchemeKey = "StackColorScheme";
+            const colorSchemeItem = localStorage.getItem(colorSchemeKey);
+            const supportDarkMode =
+                window.matchMedia("(prefers-color-scheme: dark)").matches === true;
+
+            if (
+                colorSchemeItem == "dark" ||
+                (colorSchemeItem === "auto" && supportDarkMode)
+            ) {
+                document.documentElement.dataset.scheme = "dark";
+            } else {
+                document.documentElement.dataset.scheme = "light";
+            }
+        })();
+    </script>
+    <div class="container main-container flex on-phone--column extended">
+        <aside class="sidebar left-sidebar sticky">
+            <button
+                class="hamburger hamburger--spin"
+                type="button"
+                id="toggle-menu"
+                aria-label="Toggle Menu">
+                <span class="hamburger-box">
+                    <span class="hamburger-inner"></span>
+                </span>
+            </button>
+
+            <header>
+                <figure class="site-avatar">
+                    <a href="https://demo.stack.jimmycai.com/">
+                        <img
+                            src="{{ $user['avatar'] ?? '' }}"
+                            width="300"
+                            height="300"
+                            class="site-logo"
+                            loading="lazy"
+                            alt="Avatar" />
+                    </a>
+
+                    <span class="emoji" style="font-size: 11px;">LV10</span>
+                </figure>
+
+                <div class="site-meta">
+                    <h1 class="site-name">
+                        <a href="https://demo.stack.jimmycai.com/">{{ $user["nickName"] }}</a>
+                    </h1>
+                    <h2 class="site-description">
+                        Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+                    </h2>
+                </div>
+            </header>
+            <ol class="menu-social">
+                <li>
+                    <a
+                        href="https://github.com/CaiJimmy/hugo-theme-stack"
+                        target="_blank"
+                        title="GitHub"
+                        rel="me">
+                        <svg
+                            xmlns="http://www.w3.org/2000/svg"
+                            class="icon icon-tabler icon-tabler-brand-github"
+                            width="24"
+                            height="24"
+                            viewBox="0 0 24 24"
+                            stroke-width="2"
+                            stroke="currentColor"
+                            fill="none"
+                            stroke-linecap="round"
+                            stroke-linejoin="round">
+                            <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
+                            <path
+                                d="M9 19c-4.3 1.4 -4.3 -2.5 -6 -3m12 5v-3.5c0 -1 .1 -1.4 -.5 -2c2.8 -.3 5.5 -1.4 5.5 -6a4.6 4.6 0 0 0 -1.3 -3.2a4.2 4.2 0 0 0 -.1 -3.2s-1.1 -.3 -3.5 1.3a12.3 12.3 0 0 0 -6.2 0c-2.4 -1.6 -3.5 -1.3 -3.5 -1.3a4.2 4.2 0 0 0 -.1 3.2a4.6 4.6 0 0 0 -1.3 3.2c0 4.6 2.7 5.7 5.5 6c-.6 .6 -.6 1.2 -.5 2v3.5"></path>
+                        </svg>
+                    </a>
+                </li>
+
+                <li>
+                    <a
+                        href="https://twitter.com/"
+                        target="_blank"
+                        title="Twitter"
+                        rel="me">
+                        <svg
+                            xmlns="http://www.w3.org/2000/svg"
+                            class="icon icon-tabler icon-tabler-brand-twitter"
+                            width="24"
+                            height="24"
+                            viewBox="0 0 24 24"
+                            stroke-width="2"
+                            stroke="currentColor"
+                            fill="none"
+                            stroke-linecap="round"
+                            stroke-linejoin="round">
+                            <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
+                            <path
+                                d="M22 4.01c-1 .49 -1.98 .689 -3 .99c-1.121 -1.265 -2.783 -1.335 -4.38 -.737s-2.643 2.06 -2.62 3.737v1c-3.245 .083 -6.135 -1.395 -8 -4c0 0 -4.182 7.433 4 11c-1.872 1.247 -3.739 2.088 -6 2c3.308 1.803 6.913 2.423 10.034 1.517c3.58 -1.04 6.522 -3.723 7.651 -7.742a13.84 13.84 0 0 0 .497 -3.753c-.002 -.249 1.51 -2.772 1.818 -4.013z"></path>
+                        </svg>
+                    </a>
+                </li>
+            </ol>
+            <ol class="menu" id="main-menu">
+                <li class="current">
+                    <a href="https://demo.stack.jimmycai.com/">
+                        <svg
+                            xmlns="http://www.w3.org/2000/svg"
+                            class="icon icon-tabler icon-tabler-home"
+                            width="24"
+                            height="24"
+                            viewBox="0 0 24 24"
+                            stroke-width="2"
+                            stroke="currentColor"
+                            fill="none"
+                            stroke-linecap="round"
+                            stroke-linejoin="round">
+                            <path stroke="none" d="M0 0h24v24H0z"></path>
+                            <polyline points="5 12 3 12 12 3 21 12 19 12"></polyline>
+                            <path d="M5 12v7a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-7"></path>
+                            <path d="M9 21v-6a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v6"></path>
+                        </svg>
+
+                        <span>Home</span>
+                    </a>
+                </li>
+
+                <li>
+                    <a href="https://demo.stack.jimmycai.com/archives/">
+                        <svg
+                            xmlns="http://www.w3.org/2000/svg"
+                            class="icon icon-tabler icon-tabler-archive"
+                            width="24"
+                            height="24"
+                            viewBox="0 0 24 24"
+                            stroke-width="2"
+                            stroke="currentColor"
+                            fill="none"
+                            stroke-linecap="round"
+                            stroke-linejoin="round">
+                            <path stroke="none" d="M0 0h24v24H0z"></path>
+                            <rect x="3" y="4" width="18" height="4" rx="2"></rect>
+                            <path d="M5 8v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-10"></path>
+                            <line x1="10" y1="12" x2="14" y2="12"></line>
+                        </svg>
+
+                        <span>Archives</span>
+                    </a>
+                </li>
+
+                <li>
+                    <a href="https://demo.stack.jimmycai.com/search/">
+                        <svg
+                            xmlns="http://www.w3.org/2000/svg"
+                            class="icon icon-tabler icon-tabler-search"
+                            width="24"
+                            height="24"
+                            viewBox="0 0 24 24"
+                            stroke-width="2"
+                            stroke="currentColor"
+                            fill="none"
+                            stroke-linecap="round"
+                            stroke-linejoin="round">
+                            <path stroke="none" d="M0 0h24v24H0z"></path>
+                            <circle cx="10" cy="10" r="7"></circle>
+                            <line x1="21" y1="21" x2="15" y2="15"></line>
+                        </svg>
+
+                        <span>Search</span>
+                    </a>
+                </li>
+
+                <li>
+                    <a href="https://demo.stack.jimmycai.com/links/">
+                        <svg
+                            xmlns="http://www.w3.org/2000/svg"
+                            class="icon icon-tabler icon-tabler-link"
+                            width="24"
+                            height="24"
+                            viewBox="0 0 24 24"
+                            stroke-width="2"
+                            stroke="currentColor"
+                            fill="none"
+                            stroke-linecap="round"
+                            stroke-linejoin="round">
+                            <path stroke="none" d="M0 0h24v24H0z"></path>
+                            <path
+                                d="M10 14a3.5 3.5 0 0 0 5 0l4 -4a3.5 3.5 0 0 0 -5 -5l-.5 .5"></path>
+                            <path
+                                d="M14 10a3.5 3.5 0 0 0 -5 0l-4 4a3.5 3.5 0 0 0 5 5l.5 -.5"></path>
+                        </svg>
+
+                        <span>Links</span>
+                    </a>
+                </li>
+
+                <li class="menu-bottom-section">
+                    <ol class="menu">
+                        <li id="dark-mode-toggle">
+                            <svg
+                                xmlns="http://www.w3.org/2000/svg"
+                                class="icon icon-tabler icon-tabler-toggle-left"
+                                width="24"
+                                height="24"
+                                viewBox="0 0 24 24"
+                                stroke-width="2"
+                                stroke="currentColor"
+                                fill="none"
+                                stroke-linecap="round"
+                                stroke-linejoin="round">
+                                <path stroke="none" d="M0 0h24v24H0z"></path>
+                                <circle cx="8" cy="12" r="2"></circle>
+                                <rect x="2" y="6" width="20" height="12" rx="6"></rect>
+                            </svg>
+
+                            <svg
+                                xmlns="http://www.w3.org/2000/svg"
+                                class="icon icon-tabler icon-tabler-toggle-right"
+                                width="24"
+                                height="24"
+                                viewBox="0 0 24 24"
+                                stroke-width="2"
+                                stroke="currentColor"
+                                fill="none"
+                                stroke-linecap="round"
+                                stroke-linejoin="round">
+                                <path stroke="none" d="M0 0h24v24H0z"></path>
+                                <circle cx="16" cy="12" r="2"></circle>
+                                <rect x="2" y="6" width="20" height="12" rx="6"></rect>
+                            </svg>
+
+                            <span>Dark Mode</span>
+                        </li>
+                    </ol>
+                </li>
+            </ol>
+        </aside>
+
+        <aside class="sidebar right-sidebar sticky">
+            <form
+                action="https://demo.stack.jimmycai.com/search/"
+                class="search-form widget">
+                <p>
+                    <label>Search</label>
+                    <input name="keyword" required="" placeholder="Type something..." />
+
+                    <button title="Search">
+                        <svg
+                            xmlns="http://www.w3.org/2000/svg"
+                            class="icon icon-tabler icon-tabler-search"
+                            width="24"
+                            height="24"
+                            viewBox="0 0 24 24"
+                            stroke-width="2"
+                            stroke="currentColor"
+                            fill="none"
+                            stroke-linecap="round"
+                            stroke-linejoin="round">
+                            <path stroke="none" d="M0 0h24v24H0z"></path>
+                            <circle cx="10" cy="10" r="7"></circle>
+                            <line x1="21" y1="21" x2="15" y2="15"></line>
+                        </svg>
+                    </button>
+                </p>
+            </form>
+
+            <section class="widget archives">
+                <div class="widget-icon">
+                    <svg
+                        xmlns="http://www.w3.org/2000/svg"
+                        class="icon icon-tabler icon-tabler-infinity"
+                        width="24"
+                        height="24"
+                        viewBox="0 0 24 24"
+                        stroke-width="2"
+                        stroke="currentColor"
+                        fill="none"
+                        stroke-linecap="round"
+                        stroke-linejoin="round">
+                        <path stroke="none" d="M0 0h24v24H0z"></path>
+                        <path
+                            d="M9.828 9.172a4 4 0 1 0 0 5.656 a10 10 0 0 0 2.172 -2.828a10 10 0 0 1 2.172 -2.828 a4 4 0 1 1 0 5.656a10 10 0 0 1 -2.172 -2.828a10 10 0 0 0 -2.172 -2.828"></path>
+                    </svg>
+                </div>
+                <h2 class="widget-title section-title">Archives</h2>
+
+                <div class="widget-archive--list">
+                    <div class="archives-year">
+                        <a href="https://demo.stack.jimmycai.com/archives/#2023">
+                            <span class="year">2023</span>
+                            <span class="count">4</span>
+                        </a>
+                    </div>
+                    <div class="archives-year">
+                        <a href="https://demo.stack.jimmycai.com/archives/#2022">
+                            <span class="year">2022</span>
+                            <span class="count">1</span>
+                        </a>
+                    </div>
+                </div>
+            </section>
+
+            <section class="widget tagCloud">
+                <div class="widget-icon">
+                    <svg
+                        xmlns="http://www.w3.org/2000/svg"
+                        class="icon icon-tabler icon-tabler-hash"
+                        width="24"
+                        height="24"
+                        viewBox="0 0 24 24"
+                        stroke-width="2"
+                        stroke="currentColor"
+                        fill="none"
+                        stroke-linecap="round"
+                        stroke-linejoin="round">
+                        <path stroke="none" d="M0 0h24v24H0z"></path>
+                        <line x1="5" y1="9" x2="19" y2="9"></line>
+                        <line x1="5" y1="15" x2="19" y2="15"></line>
+                        <line x1="11" y1="4" x2="7" y2="20"></line>
+                        <line x1="17" y1="4" x2="13" y2="20"></line>
+                    </svg>
+                </div>
+                <h2 class="widget-title section-title">Categories</h2>
+
+                <div class="tagCloud-tags">
+                    @foreach($categories as $category)
+                    <a
+                        href="{{ route('blog.category', ['user' => $user['userName'],'category1' => $category['id'],]) }}"
+                        class="font_size_1">
+                        {{ $category['label'] }}
+                    </a>
+                    @endforeach
+                </div>
+            </section>
+
+            <section class="widget tagCloud">
+                <div class="widget-icon">
+                    <svg
+                        xmlns="http://www.w3.org/2000/svg"
+                        class="icon icon-tabler icon-tabler-tag"
+                        width="24"
+                        height="24"
+                        viewBox="0 0 24 24"
+                        stroke-width="2"
+                        stroke="currentColor"
+                        fill="none"
+                        stroke-linecap="round"
+                        stroke-linejoin="round">
+                        <path stroke="none" d="M0 0h24v24H0z"></path>
+                        <path
+                            d="M11 3L20 12a1.5 1.5 0 0 1 0 2L14 20a1.5 1.5 0 0 1 -2 0L3 11v-4a4 4 0 0 1 4 -4h4"></path>
+                        <circle cx="9" cy="9" r="2"></circle>
+                    </svg>
+                </div>
+                <h2 class="widget-title section-title">Tags</h2>
+
+                <div class="tagCloud-tags">
+                    <a
+                        href="https://demo.stack.jimmycai.com/tags/css/"
+                        class="font_size_1">
+                        Css
+                    </a>
+
+                    <a
+                        href="https://demo.stack.jimmycai.com/tags/example-tag/"
+                        class="font_size_1">
+                        Example Tag
+                    </a>
+
+                    <a
+                        href="https://demo.stack.jimmycai.com/tags/html/"
+                        class="font_size_1">
+                        Html
+                    </a>
+
+                    <a
+                        href="https://demo.stack.jimmycai.com/tags/markdown/"
+                        class="font_size_1">
+                        Markdown
+                    </a>
+
+                    <a
+                        href="https://demo.stack.jimmycai.com/tags/themes/"
+                        class="font_size_1">
+                        Themes
+                    </a>
+                </div>
+            </section>
+        </aside>
+
+        <main class="main full-width">
+            <div>
+                @yield('content')
+            </div>
+
+            <footer class="site-footer">
+                <section class="copyright">
+                    2020 - 2025 wikipali
+                </section>
+
+                <section class="powerby">
+                    Theme
+                    <b><a
+                            href="https://github.com/CaiJimmy/hugo-theme-stack"
+                            target="_blank"
+                            rel="noopener"
+                            data-version="3.30.0">Stack</a></b>
+                    designed by
+                    <a href="https://jimmycai.com/" target="_blank" rel="noopener">Jimmy</a>
+                    © 2020 - 2025 Hugo Theme Stack Starter
+                </section>
+            </footer>
+        </main>
+    </div>
+    <script
+        src="{{ URL::asset('assets/js/blog/vibrant.min.js') }}"
+        integrity="sha256-awcR2jno4kI5X0zL8ex0vi2z+KMkF24hUW8WePSA9HM="
+        crossorigin="anonymous"></script>
+    <script
+        type="text/javascript"
+        src="{{ URL::asset('assets/js/blog/main.1e9a3bafd846ced4c345d084b355fb8c7bae75701c338f8a1f8a82c780137826.js') }}"
+        defer=""></script>
+    <script>
+        (function() {
+            const customFont = document.createElement("link");
+            customFont.href =
+                "https://fonts.googleapis.com/css2?family=Lato:wght@300;400;700&display=swap";
+
+            customFont.type = "text/css";
+            customFont.rel = "stylesheet";
+
+            document.head.appendChild(customFont);
+        })();
+    </script>
+</body>
+
+</html>

+ 74 - 0
api-v12/resources/views/book.blade.php

@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="UTF-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
+    <title>Universal Viewer</title>
+    <link
+        rel="stylesheet"
+        href="https://cdn.jsdelivr.net/npm/universalviewer@4.0.0/dist/uv.css" />
+    <script
+        type="application/javascript"
+        src="https://cdn.jsdelivr.net/npm/universalviewer@4.0.0/dist/umd/UV.js"></script>
+    <style>
+        #uv {
+            width: 100%;
+            height: 668px;
+        }
+
+        /* 自定义按钮样式 */
+        .custom-menu-button {
+            padding: 5px 10px;
+            margin: 0 5px;
+            cursor: pointer;
+        }
+    </style>
+</head>
+
+<body>
+    <div class="uv" id="uv"></div>
+    <div id="custom-menu">
+        <button id="get-page-id" onclick="getPageId()">获取当前页面 ID</button>
+    </div>
+    <script>
+        const data = {
+            manifest: "https://wellcomelibrary.org/iiif/b18035723/manifest",
+            embedded: true // needed for codesandbox frame
+        };
+
+        uv = UV.init("uv", data);
+
+        // 监听 Universal Viewer 初始化完成事件
+        uv.on('initialized', function() {
+            // 创建自定义按钮
+            var customButton = document.createElement('button');
+            customButton.textContent = '获取当前页面 ID';
+            customButton.className = 'custom-menu-button';
+
+            // 为自定义按钮添加点击事件监听器
+            customButton.addEventListener('click', function() {
+                // 获取当前页面的索引
+                var currentCanvas = uv.extension.getState().canvasIndex;
+                // 获取当前页面的 ID
+                var canvasId = uv.extension.getContent().canvases[currentCanvas].id;
+                // 弹出提示框显示当前页面 ID
+                alert('当前页面 ID: ' + canvasId);
+                console.info('当前页面 ID: ', canvasId)
+            });
+
+            // 获取 Universal Viewer 的菜单容器
+            var menu = document.querySelector('.options');
+            // 将自定义按钮添加到菜单容器中
+            menu.appendChild(customButton);
+        });
+
+        function getPageId() {
+            var canvas = uv.extension.helper.getCurrentCanvas();
+            console.log("当前页面 Canvas ID:", canvas.id);
+        }
+    </script>
+</body>
+
+</html>

+ 28 - 0
api-v12/resources/views/components/book-item.blade.php

@@ -0,0 +1,28 @@
+{{-- resources/views/components/book-item.blade.php --}}
+<div class="book-item">
+    <div class="card h-100">
+        <div class="card-body">
+            <div class="book-cover-container">
+                <a href="{{ route('library.book.show', $book['id']) }}" class="text-decoration-none">
+                    <img src="{{ $book['cover'] ?? 'https://via.placeholder.com/300x400?text=No+Cover' }}"
+                        alt="{{ $book['title'] ?? '未知书籍' }}"
+                        class="book-cover"
+                        loading="lazy">
+                </a>
+            </div>
+            <div class="book-info">
+                <div class="book-title">{{ $book['title'] ?? '未知书籍' }}</div>
+                <div class="book-author">{{ $book['author'] ?? '未知作者' }}</div>
+                <div class="book-author">
+                    <a href="{{ route('blog.index', ['user' => $book['publisher']->username]) }}">
+                        {{ $book['publisher']->nickname }}
+                    </a>
+                </div>
+                <div class="book-language">
+                    <span class="language-badge">{{ $book['language'] ?? '未知语言' }}</span>
+                    <span class="language-badge">{{ $book['type'] ?? '未知类型' }}</span>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>

+ 118 - 0
api-v12/resources/views/components/book-list.blade.php

@@ -0,0 +1,118 @@
+{{-- resources/views/components/book-list.blade.php --}}
+@once
+@push('styles')
+<link href="https://cdnjs.cloudflare.com/ajax/libs/tabler/1.0.0-beta19/css/tabler.min.css" rel="stylesheet">
+<style>
+    .book-list-container {
+        max-width: 1024px;
+        margin: 0 auto;
+        padding: 20px;
+    }
+
+    .book-item {
+        margin-bottom: 24px;
+        transition: all 0.3s ease;
+    }
+
+    .book-item:hover {
+        transform: translateY(-2px);
+        box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
+    }
+
+    .book-cover {
+        width: 100%;
+        aspect-ratio: 3/4;
+        object-fit: contain !important;
+        border-radius: 6px;
+        background-color: #f8f9fa;
+    }
+
+    .book-info {
+        padding: 16px 0;
+    }
+
+    .book-title {
+        font-size: 1.125rem;
+        font-weight: 600;
+        color: #1f2937;
+        margin-bottom: 8px;
+        line-height: 1.4;
+    }
+
+    .book-author {
+        color: #6b7280;
+        font-size: 0.95rem;
+        margin-bottom: 6px;
+    }
+
+    .book-language {
+        color: #9ca3af;
+        font-size: 0.875rem;
+    }
+
+    .language-badge {
+        display: inline-block;
+        padding: 2px 8px;
+        background-color: #e5e7eb;
+        color: #374151;
+        border-radius: 12px;
+        font-size: 0.75rem;
+        font-weight: 500;
+    }
+
+    /* 桌面端布局 */
+    @media (min-width: 576px) {
+        .book-grid {
+            display: grid;
+            grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
+            gap: 24px;
+        }
+    }
+
+    /* 手机端布局 */
+    @media (max-width: 575px) {
+        .book-item .card-body {
+            display: flex;
+            gap: 16px;
+            align-items: stretch;
+        }
+
+        .book-cover-container {
+            flex: 0 0 120px;
+        }
+
+        .book-cover {
+            height: 160px;
+            width: 120px;
+        }
+
+        .book-info {
+            flex: 1;
+            padding: 0;
+            display: flex;
+            flex-direction: column;
+            justify-content: space-between;
+        }
+
+        .book-title {
+            font-size: 1rem;
+            margin-bottom: 12px;
+        }
+    }
+</style>
+@endpush
+@endonce
+
+<div>
+    @if(!empty($books) && count($books) > 0)
+    <div class="book-grid">
+        @foreach($books as $book)
+        @include('components.book-item', ['book' => $book])
+        @endforeach
+    </div>
+    @else
+    <div class="text-center py-5">
+        <p class="text-muted">暂无图书数据</p>
+    </div>
+    @endif
+</div>

+ 29 - 0
api-v12/resources/views/components/language-switcher.blade.php

@@ -0,0 +1,29 @@
+@php
+$currentLocale = app()->getLocale();
+$languages = config('mint.languages');
+$currentLanguage = $languages[$currentLocale] ?? 'English';
+@endphp
+
+<div class="dropdown">
+    <a class="btn btn-ghost d-flex align-items-center" type="button" data-bs-toggle="dropdown" aria-expanded="false">
+        <svg t="1749033276791" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4471" width="200" height="200" fill="currentColor">
+            <path d="M512 929.959184c-230.4 0-417.959184-187.559184-417.959184-417.959184s187.559184-417.959184 417.959184-417.959184 417.959184 187.559184 417.959184 417.959184-187.559184 417.959184-417.959184 417.959184z m0-794.122449c-207.412245 0-376.163265 168.75102-376.163265 376.163265s168.75102 376.163265 376.163265 376.163265 376.163265-168.75102 376.163265-376.163265-168.75102-376.163265-376.163265-376.163265z" fill="#333333" p-id="4472"></path>
+            <path d="M512 929.959184c-11.493878 0-20.897959-9.404082-20.897959-20.89796V114.938776c0-11.493878 9.404082-20.897959 20.897959-20.89796s20.897959 9.404082 20.897959 20.89796v794.122448c0 11.493878-9.404082 20.897959-20.897959 20.89796z" fill="#333333" p-id="4473"></path>
+            <path d="M909.061224 532.897959H114.938776c-11.493878 0-20.897959-9.404082-20.89796-20.897959s9.404082-20.897959 20.89796-20.897959h794.122448c11.493878 0 20.897959 9.404082 20.89796 20.897959s-9.404082 20.897959-20.89796 20.897959z" fill="#333333" p-id="4474"></path>
+            <path d="M227.787755 809.795918c-5.22449 0-10.971429-2.089796-15.15102-6.269387C136.359184 725.159184 94.040816 621.191837 94.040816 512s42.318367-213.159184 118.595919-291.526531c7.836735-8.359184 21.420408-8.359184 29.779592-0.522449 8.359184 7.836735 8.359184 21.420408 0.522449 29.779592C173.97551 320.261224 135.836735 413.257143 135.836735 512s38.138776 191.738776 106.579592 262.269388c7.836735 8.359184 7.836735 21.420408-0.522449 29.779592-3.657143 3.657143-8.881633 5.746939-14.106123 5.746938z" fill="#333333" p-id="4475"></path>
+            <path d="M504.163265 929.959184c-0.522449 0-0.522449 0 0 0-110.759184-2.089796-214.204082-47.020408-291.52653-126.432653-7.836735-8.359184-7.836735-20.897959 0-29.257143 39.183673-40.228571 84.636735-71.57551 135.836734-92.995919 5.22449-2.089796 10.971429-2.089796 16.195919 0s9.404082 6.269388 11.493877 11.493878c29.779592 76.8 78.889796 146.285714 141.583674 200.097959 6.791837 5.746939 8.881633 15.15102 5.746939 23.510204-3.134694 7.836735-10.971429 13.583673-19.330613 13.583674z m-246.595918-141.061225c53.289796 49.110204 118.073469 80.979592 188.604082 93.518368-42.318367-44.930612-76.277551-97.17551-100.832653-153.6-31.869388 15.673469-61.64898 35.526531-87.771429 60.081632zM356.310204 344.293878c-2.612245 0-5.746939-0.522449-8.359184-1.567347-51.2-21.942857-96.653061-53.289796-135.836734-92.995919-7.836735-8.359184-7.836735-20.897959 0-29.257143C289.959184 141.061224 392.881633 96.653061 503.640816 94.040816c8.881633-0.522449 16.718367 5.22449 19.853062 13.583674s0.522449 17.763265-5.746939 23.510204C454.530612 184.946939 405.420408 253.910204 375.640816 331.232653c-2.089796 5.22449-6.269388 9.404082-11.493877 11.493878-2.089796 1.044898-5.22449 1.567347-7.836735 1.567347zM257.567347 235.102041c26.644898 24.555102 55.902041 44.408163 87.771429 60.604081 24.555102-56.42449 59.036735-108.669388 100.832653-153.6-70.530612 12.016327-135.314286 43.885714-188.604082 92.995919zM796.212245 809.795918c-5.22449 0-10.44898-2.089796-14.628572-5.746938-8.359184-7.836735-8.359184-21.420408-0.522449-29.779592C850.02449 703.738776 888.163265 610.742857 888.163265 512s-38.138776-191.738776-106.579592-262.269388c-7.836735-8.359184-7.836735-21.420408 0.522449-29.779592 8.359184-7.836735 21.420408-7.836735 29.779592 0.522449C887.640816 298.840816 929.959184 402.808163 929.959184 512s-42.318367 213.159184-118.595919 291.526531c-4.179592 4.179592-9.404082 6.269388-15.15102 6.269387z" fill="#333333" p-id="4476"></path>
+            <path d="M514.612245 929.959184c-8.881633 0-16.718367-5.22449-19.330612-13.583674-3.134694-8.359184-0.522449-17.240816 5.746938-22.987755 63.738776-54.334694 112.84898-124.342857 142.628572-202.187755 2.089796-5.22449 6.269388-9.404082 11.493877-11.493878 5.22449-2.089796 10.971429-2.089796 16.195919 0 52.767347 21.942857 100.310204 53.812245 140.538775 95.085715 7.836735 8.359184 7.836735 20.897959 0 29.257143-78.889796 80.457143-184.42449 124.865306-297.273469 125.910204z m159.869388-203.755102c-25.077551 57.991837-59.559184 111.281633-102.922449 157.257142 72.620408-11.493878 140.016327-43.885714 194.873469-94.563265-27.689796-25.6-58.514286-46.497959-91.95102-62.693877zM662.987755 346.383673c-2.612245 0-5.746939-0.522449-8.359184-1.567346-5.22449-2.089796-9.404082-6.269388-11.493877-11.493878-29.779592-77.844898-78.889796-147.853061-142.628572-202.187755-6.791837-5.746939-8.881633-15.15102-5.746938-22.987755 3.134694-8.359184 10.971429-13.583673 19.330612-13.583674 112.84898 0.522449 217.861224 45.453061 296.75102 126.432653 7.836735 8.359184 7.836735 20.897959 0 29.257143-40.228571 41.273469-87.24898 73.142857-140.538775 95.085715-1.567347 0.522449-4.702041 1.044898-7.314286 1.044897z m-91.428571-205.844897c42.840816 45.97551 77.844898 99.265306 102.922449 157.257142 33.436735-16.195918 64.783673-37.093878 91.95102-62.693877-54.857143-50.677551-122.253061-83.069388-194.873469-94.563265z" fill="#333333" p-id="4477"></path>
+            <path d="M356.310204 721.502041c-2.612245 0-5.746939-0.522449-8.359184-1.567347-5.22449-2.089796-9.404082-6.269388-11.493877-11.493878-24.032653-62.693878-36.571429-128.522449-36.571429-195.918367s12.016327-133.22449 36.571429-195.918367c2.089796-5.22449 6.269388-9.404082 11.493877-11.493878s10.971429-2.089796 16.195919 0c47.020408 19.330612 96.653061 29.257143 147.853061 29.257143 49.632653 0 97.697959-9.404082 143.15102-28.212245 5.22449-2.089796 10.971429-2.089796 16.195919 0s9.404082 6.269388 11.493877 11.493878c23.510204 62.171429 35.526531 127.477551 35.526531 193.828571 0 66.873469-12.016327 132.179592-35.526531 193.828571-2.089796 5.22449-6.269388 9.404082-11.493877 11.493878-5.22449 2.089796-10.971429 2.089796-16.195919 0-45.453061-18.808163-93.518367-28.212245-143.15102-28.212245-51.2 0-100.832653 9.926531-147.330612 29.779592-2.612245 2.612245-5.746939 3.134694-8.359184 3.134694z m12.538776-370.416327c-17.763265 51.722449-26.644898 106.057143-26.644898 160.914286s8.881633 109.191837 26.644898 160.914286c45.97551-16.718367 94.040816-25.077551 143.15102-25.077551 47.542857 0 94.040816 7.836735 138.44898 23.510204 17.240816-51.2 26.122449-105.012245 26.122449-159.346939 0-54.857143-8.881633-108.146939-26.122449-159.346939-44.408163 15.673469-90.906122 23.510204-138.44898 23.510204-49.632653 0-97.697959-8.359184-143.15102-25.077551z" fill="#333333" p-id="4478"></path>
+        </svg>
+        {{ $currentLanguage }}
+    </a>
+    <ul class="dropdown-menu">
+        @foreach ($languages as $locale => $language)
+        <li>
+            <a class="dropdown-item" href="{{ route(Route::currentRouteName(), array_merge(request()->route()->parameters(), ['lang' => $locale])) }}">
+                {{ $language }}
+            </a>
+        </li>
+        @endforeach
+    </ul>
+</div>

+ 15 - 0
api-v12/resources/views/emails/certification/en-US.blade.php

@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+    <title>email certification</title>
+</head>
+
+<body>
+    <div>wikipali email certification</div>
+    <div>wikipali sign up email certification.</div>
+    <div><b>{{ $code }}</b></div>
+    <div>This email is sent automatically by system, please don't reply.</div>
+</body>
+
+</html>

+ 15 - 0
api-v12/resources/views/emails/certification/en.blade.php

@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+    <title>email certification</title>
+</head>
+
+<body>
+    <div>wikipali email certification</div>
+    <div>wikipali sign up email certification.</div>
+    <div><b>{{ $code }}</b></div>
+    <div>This email is sent automatically by system, please don't reply.</div>
+</body>
+
+</html>

+ 18 - 0
api-v12/resources/views/emails/certification/zh-Hans.blade.php

@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+    <title>invite</title>
+</head>
+
+<body>
+    <h2>验证你的电子邮件地址</h2>
+    <div>你好:</div>
+    <div>已收到用此邮箱注册wikipali账号的请求。要完成此流程,请在验证页面输入以下代码:</div>
+    <h3>{{ $code }}</h3>
+    <div>该验证码三十分钟内有效</div>
+    <div>如果你未曾注册wikipali账号,请忽略此邮件。如果你反复收到此邮件,请联系wikipali管理员</div>
+    <div>此邮件为系统自动发送,请勿回复。</div>
+</body>
+
+</html>

+ 15 - 0
api-v12/resources/views/emails/certification/zh-Hant.blade.php

@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+    <title>invite</title>
+</head>
+
+<body>
+    <div>wikipali 注册邮箱验证码</div>
+    <div>使用下面的邮箱验证码。</div>
+    <div><b>{{ $code }}</b></div>
+    <div>此郵件為係統自動發送,請勿回複。</div>
+</body>
+
+</html>

+ 13 - 0
api-v12/resources/views/emails/invite/en-US.blade.php

@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>invite</title>
+</head>
+<body>
+<div>wikipali sign up invitation</div>
+<div>click this link to sign up on wikipali.</div>
+<div><a href='{{ $url }}'>{{ $url }}</a></div>
+<div>This email is sent automatically by system, please don't reply.</div>
+
+</body>
+</html>

+ 14 - 0
api-v12/resources/views/emails/invite/en.blade.php

@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>invite</title>
+</head>
+<body>
+<div>wikipali sign up invitation</div>
+<div>click this link to sign up on wikipali.</div>
+<div><a href='{{ $url }}'>{{ $url }}</a></div>
+<div>This link will be expired within 7 days.<br>
+This email is sent automatically by system, please don't reply.</div>
+
+</body>
+</html>

+ 12 - 0
api-v12/resources/views/emails/invite/zh-Hans.blade.php

@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>invite</title>
+    </head>
+<body>
+<div>wikipali 注册邀请</div>
+<div>点击此链接注册wikipali账号。此链接邀请只可以注册一个账户。</div>
+<div><a href='{{ $url }}'>{{ $url }}</a></div>
+<div>此邮件为系统自动发送,请勿回复。</div>
+</body>
+</html>

+ 12 - 0
api-v12/resources/views/emails/invite/zh-Hant.blade.php

@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>invite</title>
+    </head>
+<body>
+<div>wikipali 註冊邀請</div>
+<div>點選此鏈接註冊wikipali賬號。此鏈接邀請隻可以註冊一個賬戶。</div>
+<div><a href='{{ $url }}'>{{ $url }}</a></div>
+<div>此郵件為係統自動發送,請勿回複。</div>
+</body>
+</html>

+ 13 - 0
api-v12/resources/views/emails/reset_password/en-US.blade.php

@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>reset password</title>
+    </head>
+<body>
+<div>wikipali reset password</div>
+<div>We receive request of reset password. If you </div>
+<div>click link reset password</div>
+<div><a href='{{ $url }}'>{{ $url }}</a></div>
+<div>This email is sent automatically by system, please don't reply.</div>
+</body>
+</html>

+ 13 - 0
api-v12/resources/views/emails/reset_password/en.blade.php

@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>reset password</title>
+    </head>
+<body>
+<div>wikipali reset password</div>
+<div>We receive request of reset password. If you </div>
+<div>click link reset password</div>
+<div><a href='{{ $url }}'>{{ $url }}</a></div>
+<div>This email is sent automatically by system, please don't reply.</div>
+</body>
+</html>

+ 14 - 0
api-v12/resources/views/emails/reset_password/zh-Hans.blade.php

@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>重置密码</title>
+    </head>
+<body>
+<div>wikipali 重置密码</div>
+<div>您收到此邮件是因为有人提交了密码重置请求,如果您没有做此操作,请忽略此邮件。</div>
+<div>点击此链接重置密码。</div>
+<div><a href='{{ $url }}'>{{ $url }}</a></div>
+<div>此链接包涵重置账户密码的全部信息,请勿转发。</div>
+<div>此邮件为系统自动发送,请勿回复。</div>
+</body>
+</html>

+ 13 - 0
api-v12/resources/views/emails/reset_password/zh-Hant.blade.php

@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>重置密碼</title>
+    </head>
+<body>
+<div>wikipali 重置密碼</div>
+<div>您收到此郵件是因為有人提交了密碼重置請求,如果您冇有做此操作,請忽略此郵件。</div>
+<div>點選此鏈接重置密碼。</div>
+<div><a href='{{ $url }}'>{{ $url }}</a></div>
+<div>此郵件為係統自動發送,請勿回複。</div>
+</body>
+</html>

+ 40 - 0
api-v12/resources/views/export_wbw.blade.php

@@ -0,0 +1,40 @@
+<html>
+    <head>
+        <title>export word by word data</title>
+    </head>
+    <body>
+        <div class="container">
+        <form action="/api/v2/export_wbw" method="POST">
+        channel id:<br>
+        <input type="text" name="channel" value="" />
+        <br>
+        sentence list:<br>
+        <textarea type="text" name="sent" value="Mouse"></textarea>
+        <br><br>
+        <input type="submit" value="Submit">
+        </form>
+        </div>
+
+        @foreach ($sentences as $sent)
+            <h3>{{ $sent["text"] }}</h3>
+            <div>{{ $sent["sid"] }}</div>
+            <div>
+            @foreach ($sent["data"] as $wbw)
+            <b>{{$wbw["pali"]}}:</b>
+            <span class='type' style="font-style: italic;">{{$wbw["type"]}}</span>
+            <span class='grammar' style="font-style: italic;">{{$wbw["grammar"]}}</span>
+            @if(!empty($wbw["grammar"]) && !empty($wbw["parent"]))
+                <span class='of'> of </span>
+            @endif
+            <span class="parent" >{{$wbw["parent"]}} / </span>
+
+            <span class='meaning'>{{$wbw["mean"]}}</span>
+            <span class="factors" style="color:gray;">
+                <span>({{$wbw["factors"]}}</span>
+                <span>{{$wbw["factormeaning"]}})</span>
+            </span>
+            @endforeach
+            </div>
+        @endforeach
+    </body>
+</html>

+ 7 - 0
api-v12/resources/views/home.blade.php

@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<html>
+    <body>
+	
+        <h1>Hello, 欢迎来到{{ $name }}的个人空间</h1>
+    </body>
+</html>

+ 492 - 0
api-v12/resources/views/library/book/read.blade.php

@@ -0,0 +1,492 @@
+<!DOCTYPE html>
+<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
+
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Book Reading - {{ $book['title'] }}</title>
+    <!-- Tabler CSS -->
+    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@tabler/core@1.3.2/dist/css/tabler.min.css" />
+    <!-- FontAwesome for icons -->
+    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
+
+    <script
+        src="https://cdn.jsdelivr.net/npm/@tabler/core@1.3.2/dist/js/tabler.min.js">
+    </script>
+    <style>
+        /* Custom styles for responsive layout */
+        body {
+            font-family: 'Inter', sans-serif;
+            transition: background-color 0.3s, color 0.3s;
+        }
+
+        .main-container {
+            display: flex;
+            gap: 20px;
+            padding: 20px;
+            max-width: 1400px;
+            margin: 0 auto;
+        }
+
+        .toc-sidebar {
+            width: 250px;
+            flex-shrink: 0;
+            display: none;
+        }
+
+        .content-area {
+            flex-grow: 1;
+            max-width: 100%;
+        }
+
+        .right-sidebar {
+            width: 300px;
+            flex-shrink: 0;
+            display: none;
+        }
+
+        .related-books {
+            margin-top: 30px;
+        }
+
+        .card-img-container {
+            height: 150px;
+            overflow: hidden;
+        }
+
+        .card-img-container img {
+            width: 100%;
+            height: 100%;
+            object-fit: cover;
+        }
+
+        /* Mobile: Show only content, TOC in drawer */
+        @media (max-width: 767px) {
+            .content-area {
+                width: 100%;
+            }
+
+            .main-container {
+                padding: 0;
+
+            }
+
+            .card {
+                border: none;
+            }
+        }
+
+        /* Tablet: Show TOC and content */
+        @media (min-width: 768px) {
+            .toc-sidebar {
+                display: block;
+            }
+
+            .content-area {
+                max-width: calc(100% - 270px);
+            }
+        }
+
+        /* Desktop: Show TOC, content, and right sidebar */
+        @media (min-width: 992px) {
+            .right-sidebar {
+                display: block;
+            }
+
+            .content-area {
+                max-width: calc(100% - 570px);
+            }
+        }
+
+        /* Dark mode styles */
+        .dark-mode {
+            background-color: #1a1a1a;
+            color: #ffffff;
+        }
+
+        .dark-mode .card {
+            background-color: #2a2a2a;
+            border-color: #3a3a3a;
+            color: #ffffff;
+        }
+
+        .dark-mode .navbar {
+            background-color: #2a2a2a;
+        }
+
+        .dark-mode .offcanvas {
+            background-color: #2a2a2a;
+            color: #ffffff;
+        }
+
+        .dark-mode .offcanvas .nav-link {
+            color: #ffffff;
+        }
+
+        .dark-mode .toc-sidebar,
+        .dark-mode .right-sidebar {
+            background-color: #2a2a2a;
+        }
+
+        .toc-sidebar ul {
+            list-style: none;
+            padding: 0;
+        }
+
+        .toc-sidebar ul li {
+            padding: 10px 0;
+        }
+
+        .toc-sidebar ul li a {
+            color: #206bc4;
+            text-decoration: none;
+        }
+
+        .toc-sidebar ul li a:hover {
+            text-decoration: underline;
+        }
+
+        .dark-mode .toc-sidebar ul li a {
+            color: #4dabf7;
+        }
+
+        /* Multi-level TOC styles */
+        .toc-sidebar ul,
+        .offcanvas-body ul {
+            list-style: none;
+            padding: 0;
+        }
+
+        .toc-sidebar ul li,
+        .offcanvas-body ul li {
+            padding: 5px 0;
+        }
+
+        .toc-sidebar ul li a,
+        .offcanvas-body ul li a {
+            color: #206bc4;
+            text-decoration: none;
+        }
+
+        .toc-sidebar ul li a:hover,
+        .offcanvas-body ul li a:hover {
+            text-decoration: underline;
+        }
+
+        .dark-mode .toc-sidebar ul li a,
+        .dark-mode .offcanvas-body ul li a {
+            color: #4dabf7;
+        }
+
+        /* Indentation for TOC levels */
+        .toc-level-1 {
+            padding-left: 0 !important;
+        }
+
+        .toc-level-2 {
+            padding-left: 10px !important;
+        }
+
+        .toc-level-3 {
+            padding-left: 20px !important;
+        }
+
+        .toc-level-4 {
+            padding-left: 30px !important;
+        }
+
+        /* Disabled TOC item styles */
+        .toc-disabled {
+            color: #6c757d;
+            cursor: not-allowed;
+            pointer-events: none;
+        }
+
+        .dark-mode .toc-disabled {
+            color: #adb5bd;
+        }
+    </style>
+</head>
+
+<body class="{{ session('theme', 'light') }}-mode">
+    <!-- Navbar -->
+    <header class="navbar navbar-expand-md navbar-light d-print-none">
+        <div class="container-xl">
+            <button class="navbar-toggler" type="button" data-bs-toggle="offcanvas" data-bs-target="#tocDrawer" aria-controls="tocDrawer">
+                <span class="navbar-toggler-icon"></span>
+            </button>
+            <h1 class="navbar-brand">{{ $book['title'] }}</h1>
+            <div class="navbar-nav flex-row order-md-last">
+                <!-- Theme Toggle -->
+                <div class="nav-item">
+                    <a href="#" class="nav-link" id="themeToggle">
+                        <i class="fas fa-moon"></i>
+                    </a>
+                </div>
+                <!-- User Settings -->
+                <div class="nav-item dropdown">
+                    <a href="#" class="nav-link d-flex lh-1 text-reset p-0" data-bs-toggle="dropdown" aria-label="Open user menu">
+                        <span class="avatar avatar-sm" style="background-image: url({{ auth()->user()->avatar ?? 'https://via.placeholder.com/40' }})">use</span>
+                    </a>
+                    <div class="dropdown-menu dropdown-menu-end">
+                        <a class="dropdown-item" href="#">Profile</a>
+                        <a class="dropdown-item" href="#">Settings</a>
+                        <a class="dropdown-item" href="{{ route('logout') }}">Logout</a>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </header>
+
+    <!-- TOC Drawer for Mobile -->
+    <div class="offcanvas offcanvas-start" tabindex="-1" id="tocDrawer" aria-labelledby="tocDrawerLabel">
+        <div class="offcanvas-header">
+            <h5 class="offcanvas-title" id="tocDrawerLabel">Table of Contents</h5>
+            <button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
+        </div>
+        <div class="offcanvas-body">
+            @if(isset($book['toc']) && is_array($book['toc']) && count($book['toc']) > 0)
+            <ul>
+                @foreach ($book['toc'] as $index => $item)
+                <li class="toc-level-{{ $item['level'] }} {{ $item['disabled'] ? 'toc-disabled' : '' }}">
+                    @if (!$item['disabled'])
+                    <a href="{{ route('library.book.read', $item['id']) }}">{{ $item['title'] }}</a>
+                    @else
+                    <span>{{ $item['title'] }}</span>
+                    @endif
+                </li>
+                @endforeach
+            </ul>
+            @else
+            <div class="alert alert-warning">
+                此书没有目录
+            </div>
+            @endif
+        </div>
+    </div>
+
+    <!-- Main Content Area -->
+    <div class="main-container">
+        <!-- Table of Contents Sidebar (Tablet+) -->
+        <div class="toc-sidebar card">
+            <div class="card-body">
+                <h5>Table of Contents</h5>
+                @if(isset($book['toc']) && is_array($book['toc']) && count($book['toc']) > 0)
+                <ul>
+                    @foreach ($book['toc'] as $index => $item)
+                    <li class="toc-level-{{ $item['level'] }} {{ $item['disabled'] ? 'toc-disabled' : '' }}">
+                        @if (!$item['disabled'])
+                        <a href="{{ route('library.book.read', $item['id']) }}">
+                            {{ $item['title'] }}
+                        </a>
+                        @else
+                        <span>{{ $item['title'] }}</span>
+                        @endif
+                    </li>
+                    @endforeach
+                </ul>
+                @else
+                <div class="alert alert-warning">
+                    此书没有目录
+                </div>
+                @endif
+            </div>
+        </div>
+
+        <!-- Main Content -->
+        <div class="content-area card">
+
+            <div class="card-body">
+                <!-- text area -->
+                <div>
+                    <h2>{{ $book['title'] }}</h2>
+                    <p><strong>Author:</strong> <span>{{ $book['author'] }}@
+                            <a href="{{ route('blog.index', ['user' => $book['publisher']->username]) }}">
+                                {{ $book['publisher']->nickname }}
+                            </a>
+                        </span></p>
+
+                    <div class="content">
+                        @if(isset($book['content']))
+                        @foreach ($book['content'] as $index => $paragraph)
+                        <div id="para-{{ $paragraph['id'] }}">
+
+                            @foreach ($paragraph['text'] as $rows)
+                            <div style="display:flex;">
+
+                                @foreach ($rows as $col)
+                                <div style="flex:1;">
+                                    @if($paragraph['level']<8)
+                                        <h{{ $paragraph['level'] }}>{{ $col }}</h{{ $paragraph['level'] }}>
+                                        @else
+                                        <p>{{ $col }}</p>
+                                        @endif
+                                </div>
+                                @endforeach
+
+                            </div>
+                            @endforeach
+                        </div>
+                        @endforeach
+                        @else
+                        <div>没有内容</div>
+                        @endif
+                    </div>
+                </div>
+                <!-- Nav buttons -->
+                <div class="mt-6 pt-6">
+                    <ul class="pagination">
+                        @if(!empty($book["pagination"]["prev"]))
+                        <li class="page-item page-prev">
+                            <a class="page-link" href='{{ route("library.book.read",$book["pagination"]["prev"]["id"]) }}'>
+                                <div class="row align-items-center">
+                                    <div class="col-auto">
+                                        <!-- Download SVG icon from http://tabler.io/icons/icon/chevron-left -->
+                                        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-1">
+                                            <path d="M15 6l-6 6l6 6"></path>
+                                        </svg>
+                                    </div>
+                                    <div class="col">
+                                        <div class="page-item-subtitle">previous</div>
+                                        <div class="page-item-title">{{ $book["pagination"]["prev"]["title"] }}</div>
+                                    </div>
+                                </div>
+                            </a>
+                        </li>
+                        @endif
+                        @if(!empty($book["pagination"]["next"]))
+                        <li class="page-item page-next">
+                            <a class="page-link" href='{{ route("library.book.read",$book["pagination"]["next"]["id"]) }}'>
+                                <div class="row align-items-center">
+                                    <div class="col">
+                                        <div class="page-item-subtitle">next</div>
+                                        <div class="page-item-title">{{ $book["pagination"]["next"]["title"] }}</div>
+                                    </div>
+                                    <div class="col-auto">
+                                        <!-- Download SVG icon from http://tabler.io/icons/icon/chevron-right -->
+                                        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-1">
+                                            <path d="M9 6l6 6l-6 6"></path>
+                                        </svg>
+                                    </div>
+                                </div>
+                            </a>
+                        </li>
+                        @endif
+                    </ul>
+                </div>
+                <!-- Related Books -->
+                <div class="related-books">
+                    <h3>Related Books</h3>
+                    <div class="row row-cards">
+                        @if(isset($relatedBooks))
+                        @foreach ($relatedBooks as $relatedBook)
+                        <div class="col-md-4">
+                            <div class="card">
+                                <div class="card-img-container">
+                                    <img src="{{ $relatedBook['image'] }}" alt="{{ $relatedBook['title'] }}">
+                                </div>
+                                <div class="card-body">
+                                    <h5 class="card-title">{{ $relatedBook['title'] }}</h5>
+                                    <p class="card-text">{{ $relatedBook['description'] }}</p>
+                                    <a href="{{ $relatedBook['link'] }}" class="btn btn-primary">Read Now</a>
+                                </div>
+                            </div>
+                        </div>
+                        @endforeach
+                        @else
+                        <div>没有相关章节</div>
+                        @endif
+                    </div>
+                </div>
+
+            </div>
+        </div>
+
+        <!-- Right Sidebar (Desktop) -->
+        <div class="right-sidebar card">
+            <div class="card-body">
+                <h5>Download</h5>
+                <ul class="list-unstyled">
+                    @if(isset($book['downloads']))
+                    @foreach ($book['downloads'] as $download)
+                    <li><a href="{{ $download['url'] }}" class="btn btn-outline-primary mb-2 w-100"><i class="fas fa-download me-2"></i>{{ $download['format'] }}</a></li>
+                    @endforeach
+                    @else
+                    <div>没有下载链接</div>
+                    @endif
+                </ul>
+                <h5>Category</h5>
+                @foreach ($book['categories'] as $category)
+                <span class="badge bg-blue text-blue-fg">{{ $category['name'] }}</span>
+                @endforeach
+                <h5>Tags</h5>
+                <div>
+                    @foreach ($book['tags'] as $tag)
+                    <span class="badge me-1">{{ $tag['name'] }}</span>
+                    @endforeach
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <!-- Tabler JS and Bootstrap -->
+    <script src="https://cdn.jsdelivr.net/npm/@tabler/core@1.0.0-beta21/dist/js/tabler.min.js"></script>
+    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
+    <script>
+        // Theme Toggle
+        const themeToggle = document.getElementById('themeToggle');
+        const body = document.body;
+        themeToggle.addEventListener('click', (e) => {
+            e.preventDefault();
+            if (body.classList.contains('light-mode')) {
+                body.classList.remove('light-mode');
+                body.classList.add('dark-mode');
+                fetch('{{ route("theme.toggle") }}', {
+                    method: 'POST',
+                    headers: {
+                        'X-CSRF-TOKEN': '{{ csrf_token() }}',
+                        'Content-Type': 'application/json'
+                    },
+                    body: JSON.stringify({
+                        theme: 'dark'
+                    })
+                });
+                themeToggle.innerHTML = '<i class="fas fa-sun"></i>';
+            } else {
+                body.classList.remove('dark-mode');
+                body.classList.add('light-mode');
+                fetch('{{ route("theme.toggle") }}', {
+                    method: 'POST',
+                    headers: {
+                        'X-CSRF-TOKEN': '{{ csrf_token() }}',
+                        'Content-Type': 'application/json'
+                    },
+                    body: JSON.stringify({
+                        theme: 'light'
+                    })
+                });
+                themeToggle.innerHTML = '<i class="fas fa-moon"></i>';
+            }
+        });
+
+        // Smooth scroll for TOC links
+        document.querySelectorAll('.toc-sidebar a, .offcanvas-body a').forEach(anchor => {
+            anchor.addEventListener('click', function(e) {
+                e.preventDefault();
+                const targetId = this.getAttribute('href');
+                const targetElement = document.querySelector(targetId);
+                targetElement.scrollIntoView({
+                    behavior: 'smooth'
+                });
+                // Close drawer on mobile after clicking
+                if (window.innerWidth < 768) {
+                    const drawer = document.querySelector('#tocDrawer');
+                    const bsDrawer = bootstrap.Offcanvas.getInstance(drawer);
+                    bsDrawer.hide();
+                }
+            });
+        });
+    </script>
+</body>
+
+</html>

+ 143 - 0
api-v12/resources/views/library/book/show.blade.php

@@ -0,0 +1,143 @@
+@extends('library.layouts.app')
+
+@section('title', $book['title'] . ' - 巴利书库')
+
+@section('content')
+<div class="page-body">
+    <style>
+        .line2 {
+            display: -webkit-box;
+            -webkit-line-clamp: 2;
+            /* 限制显示两行 */
+            -webkit-box-orient: vertical;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            /* 超出部分显示省略号 */
+        }
+    </style>
+    <div class="container-xl">
+        <div class="page-header d-print-none">
+            <div class="row align-items-center">
+                <div class="col">
+                    <nav aria-label="breadcrumb">
+                        <ol class="breadcrumb">
+                            <li class="breadcrumb-item"><a href="{{ route('library.home') }}">{{ __('labels.home') }}</a></li>
+                            <li class="breadcrumb-item active">{{ $book['title'] }}</li>
+                        </ol>
+                    </nav>
+                </div>
+            </div>
+        </div>
+
+        <div class="row">
+            <div class="col-md-4">
+                <div class="card">
+                    <img src="{{ $book['cover'] }}" class="card-img-top" alt="{{ $book['title'] }}" style="max-height: 400px; width: fit-content;">
+                    <div class="card-body text-center">
+                        <a href="{{ route('library.book.read', $book['id']) }}" class="btn btn-primary btn-lg w-100 mb-2">
+                            <svg class="icon me-2" width="24" height="24">
+                                <use xlink:href="#tabler-book-2"></use>
+                            </svg>
+                            {{ __('buttons.online-read') }}
+                        </a>
+                        <button class="btn btn-outline-secondary w-100">
+                            <svg class="icon me-2" width="24" height="24">
+                                <use xlink:href="#tabler-download"></use>
+                            </svg>
+                            下载
+                        </button>
+                    </div>
+                </div>
+            </div>
+
+            <div class="col-md-8">
+                <div class="card">
+                    <div class="card-header">
+                        <h3 class="card-title">{{ $book['title'] }}</h3>
+                    </div>
+                    <div class="card-body">
+                        <div class="row mb-3">
+                            <div class="col-sm-3"><strong>作者:</strong></div>
+                            <div class="col-sm-9">{{ $book['author'] }}</div>
+                        </div>
+                        <div class="row mb-3">
+                            <div class="col-sm-3"><strong>出版:</strong></div>
+                            <div class="col-sm-9">
+                                <a href="{{ route('blog.index', ['user' => $book['publisher']->username]) }}">
+                                    {{ $book['publisher']->nickname }}
+                                </a>
+                            </div>
+                        </div>
+                        <div class="row mb-3">
+                            <div class="col-sm-3"><strong>语言:</strong></div>
+                            <div class="col-sm-9">{{ $book['language'] ?? '巴利语' }}</div>
+                        </div>
+                        <div class="row mb-3">
+                            <div class="col-sm-3"><strong>简介:</strong></div>
+                            <div class="col-sm-9">{{ $book['description'] }}</div>
+                        </div>
+                    </div>
+                </div>
+
+                @if(isset($book['contents']) && count($book['contents']) > 0)
+                <div class="card mt-3">
+                    <div class="card-header">
+                        <h3 class="card-title">目录</h3>
+                    </div>
+                    <div class="card-body">
+                        <div class="list-group">
+                            @foreach($book['contents'] as $chapter)
+                            <a href="{{ route('library.book.read', $chapter['id']) }}?chapter={{ $loop->iteration }}"
+                                class="list-group-item list-group-item-action">
+                                <div class="d-flex w-100 justify-content-between">
+                                    <h4 class="mb-1">{{ $chapter['title'] }}</h4>
+                                    <div class="d-flex" style="width:150px;">
+                                        @if($chapter['progress']>0)
+                                        <div class="progress">
+                                            <div class="progress-bar" style="width: {{ $chapter['progress'] }}%"></div>
+                                        </div>
+                                        @else
+                                        <small>无数据</small>
+                                        @endif
+
+                                    </div>
+
+                                </div>
+                                @if(isset($chapter['summary']))
+                                <p class="mb-1 text-muted line2">{{ $chapter['summary'] }}</p>
+                                @endif
+                            </a>
+                            @endforeach
+                        </div>
+                    </div>
+                </div>
+                @endif
+
+                @if(count($otherVersions) > 0)
+                <div class="card mt-3">
+                    <div class="card-header">
+                        <h3 class="card-title">其他版本</h3>
+                    </div>
+                    <div class="card-body">
+                        <div class="row">
+                            @foreach($otherVersions as $version)
+                            <div class="col-md-6 mb-3">
+                                <div class="d-flex">
+                                    <img src="{{ $version['cover'] }}" class="me-3" style="width: 60px; height: 80px; object-fit: cover;" alt="{{ $version['title'] }}">
+                                    <div>
+                                        <h6><a href="{{ route('library.book.show', $version['id']) }}">{{ $version['title'] }}</a></h6>
+                                        <div class="text-muted small">{{ $version['author'] }}</div>
+                                        <div class="text-muted small">{{ $version['language'] ?? '巴利语' }}</div>
+                                    </div>
+                                </div>
+                            </div>
+                            @endforeach
+                        </div>
+                    </div>
+                </div>
+                @endif
+            </div>
+        </div>
+    </div>
+</div>
+@endsection

+ 59 - 0
api-v12/resources/views/library/category.blade.php

@@ -0,0 +1,59 @@
+@extends('library.layouts.app')
+
+@section('title', $currentCategory['name'] . ' - 巴利书库')
+
+@section('content')
+<div class="page-body">
+    <div class="container-xl">
+        <div class="page-header d-print-none">
+            <div class="row align-items-center">
+                <div class="col">
+                    <nav aria-label="breadcrumb">
+                        <ol class="breadcrumb">
+                            <li class="breadcrumb-item"><a href="{{ route('library.home') }}">{{ __('labels.home') }}</a></li>
+                            @foreach($breadcrumbs as $breadcrumb)
+                            @if($loop->last)
+                            <li class="breadcrumb-item active">{{ $breadcrumb['name'] }}</li>
+                            @else
+                            <li class="breadcrumb-item">
+                                <a href="{{ route('library.category.show', $breadcrumb['id']) }}">{{ $breadcrumb['name'] }}</a>
+                            </li>
+                            @endif
+                            @endforeach
+                        </ol>
+                    </nav>
+                    <h2 class="page-title">{{ $currentCategory['name'] }}</h2>
+                </div>
+            </div>
+        </div>
+
+        @if(count($subCategories) > 0)
+        <div class="row row-cards mb-4">
+            @foreach($subCategories as $subCategory)
+            <div class="col-sm-6 col-lg-3">
+                <div class="card">
+                    <div class="card-body text-center">
+                        <a href="{{ route('library.category.show', $subCategory['id']) }}" class="btn btn-primary">
+                            {{ $subCategory['name'] }}
+                        </a>
+                    </div>
+                </div>
+            </div>
+            @endforeach
+        </div>
+        @endif
+
+
+
+        <div class="card">
+            <div class="card-header">
+                <h3 class="card-title">图书列表</h3>
+            </div>
+            <div class="card-body">
+                @include('components.book-list', ['books' => $categoryBooks])
+            </div>
+        </div>
+
+    </div>
+</div>
+@endsection

+ 42 - 0
api-v12/resources/views/library/index.blade.php

@@ -0,0 +1,42 @@
+@extends('library.layouts.app')
+
+@section('title', __('labels.home'))
+
+@section('content')
+<div class="page-body">
+    <div class="container-xl">
+        <div class="page-header d-print-none">
+            <div class="row align-items-center">
+                <div class="col">
+                    <h2 class="page-title">巴利书库</h2>
+                    <div class="text-muted mt-1">探索古老的佛教经典</div>
+                </div>
+            </div>
+        </div>
+
+        @foreach($categoryData as $data)
+        <div class="card mb-4">
+            <div class="card-header">
+                <h3 class="card-title">
+                    <svg class="icon me-2" width="24" height="24">
+                        <use xlink:href="#tabler-book"></use>
+                    </svg>
+                    {{ $data['category']['name'] }}
+                </h3>
+                <div class="card-actions">
+                    <a href="{{ route('library.category.show', $data['category']['id']) }}" class="btn btn-primary btn-sm">
+                        {{ __('buttons.more') }}
+                        <svg class="icon ms-1" width="24" height="24">
+                            <use xlink:href="#tabler-arrow-right"></use>
+                        </svg>
+                    </a>
+                </div>
+            </div>
+            <div class="card-body">
+                @include('components.book-list', ['books' => $data['books']])
+            </div>
+        </div>
+        @endforeach
+    </div>
+</div>
+@endsection

+ 192 - 0
api-v12/resources/views/library/layouts/app.blade.php

@@ -0,0 +1,192 @@
+<!doctype html>
+<html lang="zh">
+
+<head>
+    <meta charset="utf-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
+    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
+    <title>@yield('title', '巴利书库')</title>
+    @stack('styles')
+    <link href="https://cdn.jsdelivr.net/npm/@tabler/core@latest/dist/css/tabler.min.css" rel="stylesheet" />
+    <link href="https://cdn.jsdelivr.net/npm/@tabler/icons@latest/icons-sprite.svg" rel="stylesheet" />
+    <script
+        src="https://cdn.jsdelivr.net/npm/@tabler/core@1.3.2/dist/js/tabler.min.js">
+    </script>
+
+    <style>
+        .book-card {
+            transition: transform 0.2s;
+        }
+
+        .book-card:hover {
+            transform: translateY(-2px);
+        }
+
+        .book-cover {
+            height: 200px;
+            object-fit: cover;
+        }
+
+        @media (max-width: 768px) {
+            .book-cover {
+                height: 150px;
+            }
+        }
+
+        .hero-section {
+            height: 250px;
+            width: 100%;
+            background-image: url('{{ URL::asset("assets/images/hero-2.jpg") }}');
+            background-size: cover;
+            background-position: center;
+            background-repeat: no-repeat;
+            position: relative;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+        }
+
+        .hero-overlay {
+            position: absolute;
+            top: 0;
+            left: 0;
+            right: 0;
+            bottom: 0;
+            background: rgba(0, 0, 0, 0.2);
+        }
+
+        .hero-content {
+            position: relative;
+            z-index: 2;
+            text-align: center;
+            color: white;
+            max-width: 600px;
+            padding: 0 1rem;
+        }
+
+        .hero-title {
+            font-size: 2.5rem;
+            font-weight: bold;
+            margin-bottom: 1rem;
+            text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
+        }
+
+        .hero-subtitle {
+            font-size: 1.2rem;
+            margin-bottom: 2rem;
+            text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
+        }
+
+        .search-box {
+            background: white;
+            border-radius: 0.5rem;
+            padding: 0.5rem;
+            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
+            max-width: 500px;
+            margin: 0 auto;
+        }
+
+        .feature-card {
+            transition: transform 0.3s ease, box-shadow 0.3s ease;
+            height: 100%;
+        }
+
+        .feature-card:hover {
+            transform: translateY(-5px);
+            box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
+        }
+
+        .stats-section {
+            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+            color: white;
+        }
+
+        .stat-item {
+            text-align: center;
+            padding: 2rem 1rem;
+        }
+
+        .stat-number {
+            font-size: 2.5rem;
+            font-weight: bold;
+            display: block;
+        }
+
+        .stat-label {
+            font-size: 1rem;
+            opacity: 0.9;
+            margin-top: 0.5rem;
+        }
+
+        @media (max-width: 768px) {
+            .hero-title {
+                font-size: 2rem;
+            }
+
+            .hero-subtitle {
+                font-size: 1rem;
+            }
+
+            .hero-section {
+                height: 250px;
+            }
+
+            .stat-number {
+                font-size: 2rem;
+            }
+        }
+
+        @media (max-width: 576px) {
+            .hero-title {
+                font-size: 1.5rem;
+            }
+
+            .hero-subtitle {
+                font-size: 0.9rem;
+            }
+        }
+    </style>
+</head>
+
+<body>
+    <div class="page">
+        <!-- Hero Section -->
+        <section class="hero-section">
+            <div class="hero-overlay">
+                <div style="height:30px;width:100%;display: flex;justify-content: center;">
+                    <div style="color:white;flex:1;">
+                    </div>
+                    <div style="color:white;">
+                        <x-language-switcher />
+                    </div>
+                </div>
+            </div>
+
+            <div class="hero-content">
+
+                <h1 class="hero-title">巴利书库</h1>
+                <p class="hero-subtitle">探索wikipali,开启智慧之门</p>
+
+                <div class="search-box">
+                    <div class="input-group">
+                        <input type="text" class="form-control form-control-lg" placeholder="搜索图书、作者或主题...">
+                        <button class="btn btn-primary btn-lg" type="button">
+                            <i class="ti ti-search"></i>
+                        </button>
+                    </div>
+                </div>
+            </div>
+        </section>
+
+        <div class="page-wrapper">
+            @yield('content')
+        </div>
+    </div>
+
+    <!-- Tabler JS and Bootstrap -->
+    <script src="https://cdn.jsdelivr.net/npm/@tabler/core@1.0.0-beta21/dist/js/tabler.min.js"></script>
+    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
+    @stack('scripts')
+</body>
+
+</html>

+ 534 - 0
api-v12/resources/views/nissaya_format_converter.blade.php

@@ -0,0 +1,534 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>数据格式转换器</title>
+    <style>
+        * {
+            margin: 0;
+            padding: 0;
+            box-sizing: border-box;
+        }
+
+        body {
+            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
+            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+            min-height: 100vh;
+            color: #333;
+        }
+
+        .container {
+            max-width: 1200px;
+            margin: 0 auto;
+            padding: 20px;
+        }
+
+        .header {
+            text-align: center;
+            margin-bottom: 30px;
+            color: white;
+        }
+
+        .header h1 {
+            font-size: 2.5rem;
+            margin-bottom: 10px;
+            text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
+        }
+
+        .header p {
+            font-size: 1.1rem;
+            opacity: 0.9;
+        }
+
+        .converter-card {
+            background: white;
+            border-radius: 20px;
+            box-shadow: 0 20px 40px rgba(0,0,0,0.1);
+            overflow: hidden;
+            margin-bottom: 30px;
+            backdrop-filter: blur(10px);
+        }
+
+        .input-section {
+            padding: 30px;
+            background: linear-gradient(135deg, #f8f9ff 0%, #e6f2ff 100%);
+            border-bottom: 1px solid #e0e6ed;
+        }
+
+        .input-section h2 {
+            color: #2d3748;
+            margin-bottom: 15px;
+            font-size: 1.3rem;
+        }
+
+        textarea {
+            width: 100%;
+            height: 250px;
+            padding: 20px;
+            border: 2px solid #e2e8f0;
+            border-radius: 12px;
+            font-size: 14px;
+            line-height: 1.5;
+            resize: vertical;
+            transition: all 0.3s ease;
+            background: white;
+            font-family: 'Consolas', 'Monaco', monospace;
+        }
+
+        textarea:focus {
+            outline: none;
+            border-color: #667eea;
+            box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
+        }
+
+        .controls {
+            padding: 20px 30px;
+            background: #f8fafc;
+            display: flex;
+            gap: 15px;
+            flex-wrap: wrap;
+        }
+
+        .btn {
+            padding: 12px 24px;
+            border: none;
+            border-radius: 10px;
+            font-size: 14px;
+            font-weight: 600;
+            cursor: pointer;
+            transition: all 0.3s ease;
+            text-transform: uppercase;
+            letter-spacing: 0.5px;
+        }
+
+        .btn-primary {
+            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+            color: white;
+        }
+
+        .btn-primary:hover {
+            transform: translateY(-2px);
+            box-shadow: 0 10px 25px rgba(102, 126, 234, 0.3);
+        }
+
+        .btn-secondary {
+            background: #e2e8f0;
+            color: #4a5568;
+        }
+
+        .btn-secondary:hover {
+            background: #cbd5e0;
+            transform: translateY(-1px);
+        }
+
+        .btn-success {
+            background: linear-gradient(135deg, #48bb78 0%, #38a169 100%);
+            color: white;
+        }
+
+        .btn-success:hover {
+            transform: translateY(-2px);
+            box-shadow: 0 10px 25px rgba(72, 187, 120, 0.3);
+        }
+
+        .output-section {
+            padding: 30px;
+        }
+
+        .output-section h2 {
+            color: #2d3748;
+            margin-bottom: 20px;
+            font-size: 1.3rem;
+        }
+
+        .table-container {
+            background: #f8fafc;
+            border-radius: 12px;
+            padding: 20px;
+            margin-bottom: 20px;
+            overflow-x: auto;
+        }
+
+        table {
+            width: 100%;
+            border-collapse: collapse;
+            background: white;
+            border-radius: 8px;
+            overflow: hidden;
+            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
+        }
+
+        th {
+            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+            color: white;
+            padding: 15px 12px;
+            text-align: left;
+            font-weight: 600;
+            font-size: 13px;
+            text-transform: uppercase;
+            letter-spacing: 0.5px;
+        }
+
+        td {
+            padding: 12px;
+            border-bottom: 1px solid #e2e8f0;
+            vertical-align: top;
+            font-size: 14px;
+            line-height: 1.4;
+        }
+
+        tr:hover {
+            background: #f7fafc;
+        }
+
+        .csv-output {
+            background: #f8fafc;
+            border-radius: 12px;
+            padding: 20px;
+            margin-top: 20px;
+        }
+
+        .csv-content {
+            background: white;
+            border: 1px solid #e2e8f0;
+            border-radius: 8px;
+            padding: 20px;
+            font-family: 'Consolas', 'Monaco', monospace;
+            font-size: 13px;
+            line-height: 1.5;
+            max-height: 300px;
+            overflow-y: auto;
+            white-space: pre-wrap;
+        }
+
+        .status-message {
+            padding: 15px;
+            border-radius: 8px;
+            margin-bottom: 20px;
+            font-weight: 500;
+        }
+
+        .status-success {
+            background: #f0fff4;
+            color: #38a169;
+            border: 1px solid #9ae6b4;
+        }
+
+        .status-error {
+            background: #fed7d7;
+            color: #e53e3e;
+            border: 1px solid #feb2b2;
+        }
+
+        .sample-data {
+            background: #e6fffa;
+            border: 1px solid #81e6d9;
+            border-radius: 8px;
+            padding: 15px;
+            margin-top: 20px;
+        }
+
+        .sample-data h3 {
+            color: #2d3748;
+            margin-bottom: 10px;
+            font-size: 1rem;
+        }
+
+        .sample-data code {
+            background: #f7fafc;
+            padding: 2px 6px;
+            border-radius: 4px;
+            font-family: 'Consolas', 'Monaco', monospace;
+            font-size: 12px;
+        }
+
+        @media (max-width: 768px) {
+            .container {
+                padding: 10px;
+            }
+            
+            .header h1 {
+                font-size: 2rem;
+            }
+            
+            .controls {
+                flex-direction: column;
+            }
+            
+            .btn {
+                width: 100%;
+            }
+        }
+    </style>
+</head>
+<body>
+    <div class="container">
+        <div class="header">
+            <h1>📊 数据格式转换器</h1>
+            <p>将结构化文本数据转换为CSV格式,支持实时预览</p>
+        </div>
+
+        <div class="converter-card">
+            <div class="input-section">
+                <h2>📝 输入数据</h2>
+                <textarea id="inputData" placeholder="请粘贴您的数据...
+
+示例格式:
+**No**
+**Myanmar Pāḷi**
+**Nissaya**
+**Roman Pāḷi**
+**Translation**
+**Remark**
+1
+ဧဝံ မေ သုတန္တိအာဒိ၊
+ဧဝံမေသုတံ ဤသို့အစရှိသောစကားသည်။
+Evaṃ me sutantiādi,
+The word 'evam me sutam, etc.'
+2
+ကန္ဒရကသုတ္တံ၊
+ကန္ဒရကသုတ်တည်း။
+kandarakasuttaṃ,
+is the Kandaraka sutta"></textarea>
+            </div>
+
+            <div class="controls">
+                <button class="btn btn-primary" onclick="convertData()">🔄 转换数据</button>
+                <button class="btn btn-secondary" onclick="clearData()">🗑️ 清空数据</button>
+                <button class="btn btn-success" onclick="downloadCSV()" id="downloadBtn" disabled>📥 下载CSV</button>
+            </div>
+
+            <div class="output-section">
+                <h2>📋 转换结果</h2>
+                <div id="statusMessage"></div>
+                <div id="tablePreview"></div>
+                <div id="csvOutput"></div>
+            </div>
+        </div>
+
+        <div class="sample-data">
+            <h3>💡 使用说明</h3>
+            <p>1. 请确保输入数据格式正确,表头用 <code>**标题**</code> 格式标记</p>
+            <p>2. 数据行按顺序排列,每行一个字段</p>
+            <p>3. 支持多语言文本,包括缅甸语、巴利语等</p>
+            <p>4. 转换后可预览表格并下载CSV文件</p>
+        </div>
+    </div>
+
+    <script>
+        let csvData = '';
+        let tableData = [];
+
+        function showStatus(message, type = 'success') {
+            const statusDiv = document.getElementById('statusMessage');
+            statusDiv.innerHTML = `<div class="status-message status-${type}">${message}</div>`;
+            setTimeout(() => {
+                statusDiv.innerHTML = '';
+            }, 5000);
+        }
+
+        function parseData(text) {
+            const lines = text.trim().split('\n').filter(line => line.trim() !== '');
+            
+            // 提取表头
+            const headers = [];
+            let i = 0;
+            while (i < lines.length) {
+                const line = lines[i].trim();
+                if (line.startsWith('**') && line.endsWith('**')) {
+                    headers.push(line.slice(2, -2));
+                    i++;
+                } else {
+                    break;
+                }
+            }
+            
+            if (headers.length === 0) {
+                throw new Error('未找到表头,请确保表头格式为 **标题**');
+            }
+            
+            // 解析数据行
+            const data = [];
+            let currentRow = [];
+            
+            for (let j = i; j < lines.length; j++) {
+                const line = lines[j].trim();
+                
+                // 检查是否是新行的开始(数字开头)
+                if (/^\d+$/.test(line)) {
+                    // 如果当前行有数据,先保存
+                    if (currentRow.length > 0) {
+                        // 补齐缺失的列
+                        while (currentRow.length < headers.length) {
+                            currentRow.push('');
+                        }
+                        data.push([...currentRow]);
+                    }
+                    // 开始新行
+                    currentRow = [line];
+                } else if (line !== '') {
+                    // 添加到当前行
+                    currentRow.push(line);
+                }
+            }
+            
+            // 添加最后一行
+            if (currentRow.length > 0) {
+                // 补齐缺失的列
+                while (currentRow.length < headers.length) {
+                    currentRow.push('');
+                }
+                data.push(currentRow);
+            }
+            
+            return { headers, data };
+        }
+
+        function generateCSV(headers, data) {
+            const csvRows = [];
+            
+            // 添加表头
+            csvRows.push(headers.map(header => `"${header.replace(/"/g, '""')}"`).join(','));
+            
+            // 添加数据行
+            data.forEach(row => {
+                const csvRow = row.map(cell => `"${cell.replace(/"/g, '""')}"`).join(',');
+                csvRows.push(csvRow);
+            });
+            
+            return csvRows.join('\n');
+        }
+
+        function createTable(headers, data) {
+            if (data.length === 0) {
+                return '<p>没有数据可显示</p>';
+            }
+            
+            let html = '<div class="table-container"><table>';
+            
+            // 表头
+            html += '<thead><tr>';
+            headers.forEach(header => {
+                html += `<th>${header}</th>`;
+            });
+            html += '</tr></thead>';
+            
+            // 数据行
+            html += '<tbody>';
+            data.forEach(row => {
+                html += '<tr>';
+                row.forEach(cell => {
+                    html += `<td>${cell}</td>`;
+                });
+                html += '</tr>';
+            });
+            html += '</tbody>';
+            
+            html += '</table></div>';
+            return html;
+        }
+
+        function convertData() {
+            const inputText = document.getElementById('inputData').value.trim();
+            
+            if (!inputText) {
+                showStatus('请输入数据', 'error');
+                return;
+            }
+            
+            try {
+                const { headers, data } = parseData(inputText);
+                
+                console.log('解析结果:', { headers, data }); // 调试信息
+                
+                if (data.length === 0) {
+                    showStatus('未找到有效数据行', 'error');
+                    return;
+                }
+                
+                // 生成CSV
+                csvData = generateCSV(headers, data);
+                
+                // 生成表格预览
+                const tableHTML = createTable(headers, data);
+                document.getElementById('tablePreview').innerHTML = tableHTML;
+                
+                // 显示CSV内容
+                const csvHTML = `
+                    <div class="csv-output">
+                        <h3>📄 CSV格式预览</h3>
+                        <div class="csv-content">${csvData}</div>
+                    </div>
+                `;
+                document.getElementById('csvOutput').innerHTML = csvHTML;
+                
+                // 启用下载按钮
+                document.getElementById('downloadBtn').disabled = false;
+                
+                showStatus(`转换成功!共转换 ${data.length} 行数据,${headers.length} 个字段`, 'success');
+                
+            } catch (error) {
+                showStatus(`转换失败:${error.message}`, 'error');
+                console.error('转换错误:', error);
+            }
+        }
+
+        function clearData() {
+            document.getElementById('inputData').value = '';
+            document.getElementById('tablePreview').innerHTML = '';
+            document.getElementById('csvOutput').innerHTML = '';
+            document.getElementById('downloadBtn').disabled = true;
+            csvData = '';
+            showStatus('数据已清空', 'success');
+        }
+
+        function downloadCSV() {
+            if (!csvData) {
+                showStatus('没有可下载的数据', 'error');
+                return;
+            }
+            
+            // 添加BOM以支持Excel中的UTF-8显示
+            const BOM = '\uFEFF';
+            const blob = new Blob([BOM + csvData], { type: 'text/csv;charset=utf-8;' });
+            const link = document.createElement('a');
+            
+            if (link.download !== undefined) {
+                const url = URL.createObjectURL(blob);
+                link.setAttribute('href', url);
+                link.setAttribute('download', `converted_data_${new Date().toISOString().slice(0, 10)}.csv`);
+                link.style.visibility = 'hidden';
+                document.body.appendChild(link);
+                link.click();
+                document.body.removeChild(link);
+                showStatus('CSV文件下载完成', 'success');
+            }
+        }
+
+        // 自动加载示例数据
+        document.addEventListener('DOMContentLoaded', function() {
+            const sampleData = `**No**
+**Myanmar Pāḷi**
+**Nissaya**
+**Roman Pāḷi**
+**Translation**
+**Remark**
+1
+ဧဝံ မေ သုတန္တိအာဒိ၊
+ဧဝံမေသုတံ ဤသို့အစရှိသောစကားသည်။
+Evaṃ me sutantiādi,
+The word 'evam me sutam, etc.'
+
+2
+ကန္ဒရကသုတ္တံ၊
+ကန္ဒရကသုတ်တည်း။
+kandarakasuttaṃ,
+is the Kandaraka sutta
+`;
+            
+            document.getElementById('inputData').value = sampleData;
+        });
+    </script>
+</body>
+</html>

+ 9 - 0
api-v12/resources/views/privacy.blade.php

@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>wikipali app 隐私政策</title>
+    </head>
+    <body>
+        {{ Illuminate\Mail\Markdown::parse($content) }}
+    </body>
+</html>

Різницю між файлами не показано, бо вона завелика
+ 397 - 0
api-v12/resources/views/solarize.blade.php


+ 860 - 0
api-v12/resources/views/typhoon.blade.php

@@ -0,0 +1,860 @@
+
+<!DOCTYPE html>
+<html lang="en" data-appearance="{&quot;appearance&quot;:&quot;system&quot;,&quot;store&quot;:1}" x-data="{ show_mobile_nav: false, theme: typhoonRetrieve().theme, appearance: typhoonRetrieve().appearance }" :class="[ show_mobile_nav ? 'overflow-hidden' : '', theme ]" class="overflow-x-hidden">
+<head>
+<meta charset="utf-8" />
+<title>wikipali-{{ $title }}</title>
+<meta http-equiv="X-UA-Compatible" content="IE=edge" />
+<meta name="viewport" content="width=device-width, initial-scale=1" />
+<meta name="description" content="{{ $description }}" />
+<link rel="icon" href="/assets/images/favicon.ico" />
+<link rel="canonical" href="https://www.wikipali.org/" />
+<link href="/assets/typhoon/css/notices.css" type="text/css" rel="stylesheet">
+<link href="/assets/typhoon/css/glightbox.min.css" type="text/css" rel="stylesheet">
+<link href="/assets/typhoon/css/site.css" type="text/css" rel="stylesheet">
+<link href="/assets/typhoon/css/form-styles.css" type="text/css" rel="stylesheet">
+<style>
+:root {
+  --color-primary: #FF4C41;
+  --color-primary__lighter: #ffaca7;
+  --color-primary__darker: #da0d00;
+}
+#sign_in {
+    display:none;
+}
+</style>
+<script src="/assets/typhoon/js/alpine.js" defer></script>
+</head>
+<body id="top" class="flex flex-col items-stretch min-h-screen antialiased relative bg-white dark:bg-gray-900 overflow-x-hidden text-gray-600 dark:text-gray-400 " @typhoon-theme.window="theme = $event.detail.theme || ''; appearance = $event.detail.appearance || '';">
+<div class="relative bg-orange-300">
+<div class="max-w-screen-xl mx-auto py-3 px-3 sm:px-6 lg:px-8" style='display:none'>
+notification
+</div>
+</div>
+<div class="flex-1 flex flex-col relative">
+<header class="absolute w-full z-10 pb-1 h-16 flex items-center " style>
+<div class="flex-auto xl:container xl:mx-auto md:px-6 px-4">
+<nav class="header-nav relative flex items-center justify-between lg:justify-start animated ">
+<div class="flex items-center">
+<div class="flex items-center justify-between w-full md:w-auto">
+<a href="/pcd/community/list" aria-label="Logo" class="text-gray-200">
+<div class="site-logo h-8" style="display:flex;">
+
+<svg id="wikipali_banner" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 221 54.417">
+  <g id="Group_12" data-name="Group 12" transform="translate(-396 -320)">
+    <g id="Group_2" data-name="Group 2" transform="translate(396 320)">
+      <g id="Group_1" data-name="Group 1" transform="translate(39.472 12.369)">
+        <path id="Path_1" data-name="Path 1"
+          d="M252.239,132.886a1.184,1.184,0,0,1-.733-.244,1.144,1.144,0,0,1-.424-.63l-3.447-12.729a.825.825,0,0,1-.026-.206.683.683,0,0,1,.155-.411.655.655,0,0,1,.539-.257h1.234a1.129,1.129,0,0,1,.721.244,1.171,1.171,0,0,1,.411.63l1.7,6.97q.026.1.8,4.063a.046.046,0,0,0,.053.051.046.046,0,0,0,.051-.051q.925-3.96.952-4.063l1.8-6.97a1.187,1.187,0,0,1,1.132-.874h1a1.187,1.187,0,0,1,1.13.874l1.851,6.97q.153.643.475,1.993t.5,2.071a.046.046,0,0,0,.051.051.084.084,0,0,0,.078-.051q.076-.464.36-1.865t.462-2.2l1.647-6.97a1.187,1.187,0,0,1,1.132-.874h1.028a.66.66,0,0,1,.54.257.723.723,0,0,1,.155.437.813.813,0,0,1-.026.18l-3.266,12.729a1.143,1.143,0,0,1-.424.63,1.174,1.174,0,0,1-.733.244h-1.8a1.129,1.129,0,0,1-.721-.244,1.165,1.165,0,0,1-.411-.63l-1.62-6.3q-.258-1.028-.9-4.114a.1.1,0,0,0-.091-.051.091.091,0,0,0-.089.051q-.514,2.726-.9,4.142l-1.543,6.275a1.166,1.166,0,0,1-.411.63,1.12,1.12,0,0,1-.721.244h-1.671Z"
+          transform="translate(-247.61 -111.903)" fill="#fff" />
+        <path id="Path_2" data-name="Path 2"
+          d="M395.183,81.944a1.988,1.988,0,0,1-1.389.5,1.942,1.942,0,0,1-1.376-.5,1.661,1.661,0,0,1-.539-1.274,1.692,1.692,0,0,1,.539-1.3,1.94,1.94,0,0,1,1.376-.5,1.978,1.978,0,0,1,1.389.5,1.673,1.673,0,0,1,.553,1.3A1.644,1.644,0,0,1,395.183,81.944ZM393.216,99.65a.92.92,0,0,1-.926-.926V86.072a.864.864,0,0,1,.269-.63.892.892,0,0,1,.657-.269h1.157a.9.9,0,0,1,.657.269.865.865,0,0,1,.271.63V98.723a.923.923,0,0,1-.928.926Z"
+          transform="translate(-368.881 -78.666)" fill="#fff" />
+        <path id="Path_3" data-name="Path 3"
+          d="M444.3,98.574a.92.92,0,0,1-.926-.926V78.489a.869.869,0,0,1,.269-.63.892.892,0,0,1,.657-.269H445.4a.9.9,0,0,1,.657.269.863.863,0,0,1,.269.63v12.6c0,.018.013.026.038.026a.091.091,0,0,0,.065-.026l5.092-6.3a1.831,1.831,0,0,1,1.492-.693h1.518a.387.387,0,0,1,.373.244.382.382,0,0,1-.064.45l-4.269,5.092a.167.167,0,0,0,0,.18l4.937,7.74a.49.49,0,0,1,.078.257.481.481,0,0,1-.078.257.448.448,0,0,1-.437.257h-1.465a1.55,1.55,0,0,1-1.389-.772l-3.4-5.683c-.033-.069-.077-.077-.129-.026l-2.288,2.649a.336.336,0,0,0-.078.206v2.7a.92.92,0,0,1-.926.926Z"
+          transform="translate(-412.163 -77.59)" fill="#fff" />
+        <path id="Path_4" data-name="Path 4"
+          d="M540.613,81.944a1.987,1.987,0,0,1-1.388.5,1.94,1.94,0,0,1-1.376-.5,1.661,1.661,0,0,1-.539-1.274,1.692,1.692,0,0,1,.539-1.3,1.942,1.942,0,0,1,1.376-.5,1.977,1.977,0,0,1,1.388.5,1.673,1.673,0,0,1,.553,1.3A1.649,1.649,0,0,1,540.613,81.944ZM538.646,99.65a.923.923,0,0,1-.928-.926V86.072a.86.86,0,0,1,.271-.63.892.892,0,0,1,.657-.269H539.8a.9.9,0,0,1,.657.269.863.863,0,0,1,.269.63V98.723a.92.92,0,0,1-.926.926Z"
+          transform="translate(-491.128 -78.666)" fill="#fff" />
+        <path id="Path_5" data-name="Path 5"
+          d="M589.735,137.187a.92.92,0,0,1-.925-.925V117.746a.92.92,0,0,1,.925-.926h.642a1.016,1.016,0,0,1,.682.257,1.136,1.136,0,0,1,.373.642l.077.642c.018.035.038.053.064.053a.1.1,0,0,0,.065-.026,7.051,7.051,0,0,1,4.424-1.929,5,5,0,0,1,4.231,1.993,8.742,8.742,0,0,1,1.5,5.388,10.164,10.164,0,0,1-.515,3.3,6.991,6.991,0,0,1-1.389,2.469,6.473,6.473,0,0,1-1.993,1.5,5.339,5.339,0,0,1-2.353.54,5.846,5.846,0,0,1-3.729-1.569.031.031,0,0,0-.051,0,.075.075,0,0,0-.025.053l.076,2.366v3.754a.92.92,0,0,1-.926.925h-1.159Zm5.246-8.023a3.153,3.153,0,0,0,2.65-1.4,6.426,6.426,0,0,0,1.028-3.871q0-4.912-3.394-4.912a5.135,5.135,0,0,0-3.368,1.7.245.245,0,0,0-.078.18v6.866a.243.243,0,0,0,.078.18A4.734,4.734,0,0,0,594.981,129.164Z"
+          transform="translate(-534.418 -110.264)" fill="#fff" />
+        <path id="Path_6" data-name="Path 6"
+          d="M691.509,105.4a4.264,4.264,0,0,1-3.073-1.143,4.27,4.27,0,0,1,.85-6.609,16.4,16.4,0,0,1,6.518-1.787c.069,0,.1-.041.1-.129q-.1-3.032-2.751-3.034a7.157,7.157,0,0,0-3.419,1,.864.864,0,0,1-.669.089.811.811,0,0,1-.539-.424l-.257-.462a.955.955,0,0,1-.089-.706.822.822,0,0,1,.424-.553,10.423,10.423,0,0,1,5.066-1.44,4.826,4.826,0,0,1,3.96,1.594,6.988,6.988,0,0,1,1.312,4.551v7.792a.923.923,0,0,1-.928.926h-.642a1.008,1.008,0,0,1-.681-.257,1.118,1.118,0,0,1-.373-.642l-.1-.721c-.018-.033-.038-.053-.065-.053s-.046.018-.064.053A7.155,7.155,0,0,1,691.509,105.4Zm-.977-18.027a.92.92,0,0,1-.926-.926v-.206a.92.92,0,0,1,.926-.926h6.3a.92.92,0,0,1,.925.926v.206a.92.92,0,0,1-.925.926Zm1.9,15.637a5.287,5.287,0,0,0,3.4-1.6.278.278,0,0,0,.077-.206V97.9c0-.086-.033-.12-.1-.1a11.688,11.688,0,0,0-4.346,1.17,2.336,2.336,0,0,0-1.286,2.045,1.82,1.82,0,0,0,.617,1.518A2.582,2.582,0,0,0,692.435,103.015Z"
+          transform="translate(-617.157 -84.088)" fill="#fff" />
+        <path id="Path_7" data-name="Path 7"
+          d="M792.08,98.907a2.68,2.68,0,0,1-2.3-.952,4.607,4.607,0,0,1-.708-2.779V78.489a.865.865,0,0,1,.271-.63A.893.893,0,0,1,790,77.59h1.157a.9.9,0,0,1,.657.269.865.865,0,0,1,.271.63V95.333a1.12,1.12,0,0,0,.411,1.028c.034.018.11.061.231.129s.206.12.257.155.12.081.206.14a.691.691,0,0,1,.193.193.438.438,0,0,1,.064.231l.1.566a.736.736,0,0,1,.026.18.96.96,0,0,1-.155.54.792.792,0,0,1-.591.386C792.585,98.9,792.336,98.907,792.08,98.907Z"
+          transform="translate(-702.754 -77.59)" fill="#fff" />
+        <path id="Path_8" data-name="Path 8"
+          d="M840.663,81.944a1.988,1.988,0,0,1-1.389.5,1.94,1.94,0,0,1-1.376-.5,1.661,1.661,0,0,1-.539-1.274,1.692,1.692,0,0,1,.539-1.3,1.939,1.939,0,0,1,1.376-.5,1.978,1.978,0,0,1,1.389.5,1.673,1.673,0,0,1,.553,1.3A1.649,1.649,0,0,1,840.663,81.944ZM838.7,99.65a.92.92,0,0,1-.926-.926V86.072a.864.864,0,0,1,.269-.63.892.892,0,0,1,.657-.269h1.157a.9.9,0,0,1,.657.269.865.865,0,0,1,.271.63V98.723a.923.923,0,0,1-.928.926Z"
+          transform="translate(-743.346 -78.666)" fill="#fff" />
+      </g>
+      <path id="Path_9" data-name="Path 9"
+        d="M125.632,125.382a1.531,1.531,0,0,1-1.532-1.532v-5.532c0-8.629,4.134-13.579,11.342-13.579a1.532,1.532,0,0,1,0,3.064c-5.493,0-8.28,3.537-8.28,10.517v5.532A1.529,1.529,0,0,1,125.632,125.382Z"
+        transform="translate(-104.317 -88.043)" fill="#f1ca23" />
+      <path id="Path_10" data-name="Path 10"
+        d="M144.722,179.085a1.532,1.532,0,1,1,0-3.064c2.987,0,5.076-4,5.076-9.727V149.842a1.532,1.532,0,0,1,3.064,0v16.452C152.86,175.13,148.773,179.085,144.722,179.085Z"
+        transform="translate(-120.364 -124.667)" fill="#f1ca23" />
+      <path id="Path_11" data-name="Path 11"
+        d="M84.262,37.339a1.531,1.531,0,0,1-1.532-1.532V1.532a1.532,1.532,0,0,1,3.064,0V35.809A1.531,1.531,0,0,1,84.262,37.339Z"
+        transform="translate(-69.542)" fill="#f1ca23" />
+      <path id="Path_12" data-name="Path 12"
+        d="M42.892,37.339a1.531,1.531,0,0,1-1.532-1.532V1.532a1.532,1.532,0,0,1,3.064,0V35.809A1.531,1.531,0,0,1,42.892,37.339Z"
+        transform="translate(-34.767)" fill="#f1ca23" />
+      <path id="Path_13" data-name="Path 13"
+        d="M1.532,37.339A1.531,1.531,0,0,1,0,35.808V1.532a1.532,1.532,0,0,1,3.064,0V35.809A1.533,1.533,0,0,1,1.532,37.339Z"
+        fill="#f1ca23" />
+    </g>
+
+  </g>
+</svg>
+
+<span  id='nickname'></span>
+</div>
+</a>
+</div>
+</div>
+<div class="hidden h-full md:flex md:flex-grow justify-end">
+<ul class="flex h-16 mr-8">
+@foreach ($nav as $item)
+<li id="{{ $item['id'] }}" class="flex ml-4 text-sm relative inline-flex items-center pt-1 border-b-2 font-medium leading-5 transition duration-150 ease-in-out  border-transparent text-gray-400 hover:text-primary hover:border-primary focus:outline-none focus:text-primary focus:border-gray-300  ">
+<div class="flex w-full h-full">
+<a class="w-full flex items-center h-full px-3" href="{{ $item['link'] }}">{{ $item['title'] }}</a>
+</div>
+</li>
+@endforeach
+
+<li class="flex ml-4 text-sm relative inline-flex items-center pt-1 border-b-2 font-medium leading-5 transition duration-150 ease-in-out  border-transparent text-gray-400 hover:text-primary hover:border-primary focus:outline-none focus:text-primary focus:border-gray-300  ">
+<div class="flex w-full h-full">
+<a class="w-full flex items-center h-full px-3" href="#contact">联络我们</a>
+</div>
+</li>
+<li class="flex ml-4 text-sm relative inline-flex items-center pt-1 border-b-2 font-medium leading-5 transition duration-150 ease-in-out  border-transparent text-gray-400 hover:text-primary hover:border-primary focus:outline-none focus:text-primary focus:border-gray-300  ">
+<div class="flex w-full h-full">
+<span class="w-full flex items-center h-full px-3" id='nickname'> </span>
+</div>
+</li>
+
+</ul>
+</div>
+</nav>
+</div>
+<div class="flex items-center md:hidden justify-end">
+<button @click="show_mobile_nav = true" aria-label="Mobile menu" type="button" class="text-gray-200 inline-flex items-center justify-center p-2 mr-2 rounded-md focus:outline-none transition duration-150 ease-in-out">
+<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-menu inline-block current-color h-8 w-8" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+<path stroke="none" d="M0 0h24v24H0z" fill="none" />
+<line x1="4" y1="8" x2="20" y2="8" />
+<line x1="4" y1="16" x2="20" y2="16" />
+</svg>
+</button>
+</div>
+</header>
+<section id="hero" class="relative  overflow-hidden ">
+<img class="background-image absolute inset-0 object-cover h-full w-full" alt="Hero Image" src="{{ URL::asset('assets/images/hero.jpg') }}" />
+<div class="absolute inset-0 bg-cover bg-center bg-no-repeat" style="background-image: linear-gradient(to bottom, rgba(34,34,34,0.9), rgba(34,34,34,0.4));"></div>
+<div class="xl:container xl:mx-auto md:px-6 px-4 relative pt-32 md:pt-40 lg:pt-48 xl:pt-56 pb-16 md:pb-20 lg:pb-24 xl:pb-32">
+<div class="flex text-center justify-center">
+<div class="w-5/6 md:w-3/4 lg:w-2/3 xl:w-1/2">
+<h1 class="mt-1 tracking-tight leading-tighter text-2xl sm:text-3xl md:text-4xl lg:text-5xl font-extrabold text-gray-100">
+{{ $title }}
+</h1>
+<div class="mt-3 text-gray-200 text-lg md:text-xl">
+<p>{{ $subtitle }}</p>
+</div>
+<div class="mt-5 mt-8 flex space-x-4 justify-center">
+<div class="rounded-md shadow" style="display:none;">
+<a href="https://learn.getgrav.org" class="bg-primary hover:bg-gray-800 text-white w-full flex items-center justify-center px-8 py-3 border border-transparent text-base leading-6 font-medium rounded-md focus:outline-none focus:ring transition duration-300 ease-in-out md:py-4 md:text-lg md:px-10">
+Read the documentation
+</a>
+</div>
+</div>
+</div>
+</div>
+</div>
+</section>
+<section class="flex-1">
+<div class="pt-0">
+<div id="highlights"></div>
+<div class="bg-white dark:bg-gray-900 py-8 md:py-24">
+<div class="xl:container xl:mx-auto md:px-6 px-4">
+<div class="w-5/6 md:w-3/4 lg:w-2/3 xl:w-1/2 text-center mx-auto mb-16">
+<div class="text-xs md:text-sm opacity-75 font-semibold uppercase tracking-wide text-gray-700 dark:text-gray-300">
+让学习圣典变得更容易
+</div>
+<h2 class="mt-1 tracking-tight leading-tighter text-2xl sm:text-3xl md:text-4xl lg:text-5xl font-extrabold text-gray-900 dark:text-gray-100">
+我们的愿景
+</h2>
+<div class="mt-3 text-base md:text-lg lg:text-xl prose">
+<p>打造一个公共的巴利圣典学习平台。</p>
+</div>
+</div>
+<div class="grid md:grid-cols-2 xl:grid-cols-3 gap-y-8 gap-x-8 ">
+<div class="flex duration-300 hover:scale-105">
+<div class="flex-shrink-0">
+<div class="bg-primary text-gray-200 rounded-md p-3">
+<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-gauge inline-block w-8 h-8 stroke-current" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+<path stroke="none" d="M0 0h24v24H0z" fill="none" />
+<circle cx="12" cy="12" r="9" />
+<circle cx="12" cy="12" r="1" />
+<line x1="13.41" y1="10.59" x2="16" y2="8" />
+<path d="M7 12a5 5 0 0 1 5 -5" />
+</svg>
+</div>
+</div>
+
+<div class="ml-4">
+<a class="text-primary hover:text-primary-darker dark:hover:text-primary-lighter" href="https://getgrav.org"></a>
+<h3 class="font-bold mb-2 text-lg">
+翻译一套三藏
+</h3>
+
+<div class="prose">
+我们希望把完整的巴利三藏、义注、复注、nissaya都翻译成为中文。
+</div>
+</div>
+</div>
+<div class="flex duration-300 hover:scale-105">
+<div class="flex-shrink-0">
+<div class="bg-primary text-gray-200 rounded-md p-3">
+<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-forklift inline-block w-8 h-8 stroke-current" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+<path stroke="none" d="M0 0h24v24H0z" fill="none" />
+<circle cx="5" cy="17" r="2" />
+<circle cx="14" cy="17" r="2" />
+<line x1="7" y1="17" x2="12" y2="17" />
+<path d="M3 17v-6h13v6" />
+<path d="M5 11v-4h4" />
+<path d="M9 11v-6h4l3 6" />
+<path d="M22 15h-3v-10" />
+<line x1="16" y1="13" x2="19" y2="13" />
+</svg>
+</div>
+</div>
+
+<div class="ml-4">
+<a class="text-primary hover:text-primary-darker dark:hover:text-primary-lighter" href="https://learn.getgrav.org"></a>
+<h3 class="font-bold mb-2 text-lg">
+整理一本词典
+</h3>
+<div class="prose">
+我们希望借助沉淀下来的数据,整理一套完整的巴中字典。这项工作将在整个三藏翻译的过程中逐渐完成。
+</div>
+</div>
+</div>
+<div class="flex duration-300 hover:scale-105">
+<div class="flex-shrink-0">
+<div class="bg-primary text-gray-200 rounded-md p-3">
+<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-box inline-block w-8 h-8 stroke-current" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+<path stroke="none" d="M0 0h24v24H0z" fill="none" />
+<polyline points="12 3 20 7.5 20 16.5 12 21 4 16.5 4 7.5 12 3" />
+<line x1="12" y1="12" x2="20" y2="7.5" />
+<line x1="12" y1="12" x2="12" y2="21" />
+<line x1="12" y1="12" x2="4" y2="7.5" />
+</svg>
+</div>
+</div>
+<div class="ml-4">
+<h3 class="font-bold mb-2 text-lg">
+开发一个平台
+</h3>
+<div class="prose">
+我们会持续开发和维护wikipali平台,并不断发展新的功能,令其越来越方便与巴利翻译和研究。
+</div>
+</div>
+</div>
+</div>
+</div>
+</div>
+
+
+<div id="columns"></div>
+<div class="bg-gray-100 dark:bg-gray-800 py-8 md:py-24">
+<div class="xl:container xl:mx-auto md:px-6 px-4">
+<div class>
+<div class="w-5/6 md:w-3/4 lg:w-2/3 xl:w-1/2 text-center mx-auto mb-16">
+<div class="text-xs md:text-sm opacity-75 font-semibold uppercase tracking-wide text-gray-700 dark:text-gray-300">
+千年译经路
+</div>
+<h2 class="mt-1 tracking-tight leading-tighter text-2xl sm:text-3xl md:text-4xl lg:text-5xl font-extrabold text-gray-900 dark:text-gray-100">
+巴利三藏翻译工程
+</h2>
+</div>
+<div class="mt-3 prose col-count-1 sm:col-count-2 sm:gap-x-6 lg:col-count-3 lg:gap-x-10 xl:col-count-4 xl:gap-x-12">
+<p>上座部佛教相信,佛陀讲经说法时所使用的语言是当时中印度马嘎塔国(Magadha,摩揭陀国)一带的民众方言——马嘎塔口语。这种语言在西元前3世纪的阿首咖王(Asoka,阿育王)时代即随着到斯里兰卡传播佛教的马兴德阿拉汉而传到斯里兰卡,并一直流传到今天。</p>
+<p>由于新哈勒人原先就有了自己的语言,当以马嘎塔语为媒介语的上座部佛教传播到斯里兰卡之后,这种语言就只是作为传诵三藏圣典之用,因此马嘎塔语又被称为「巴利语」。</p>
+<p>义注起源于佛陀在世时弟子们对佛陀教导的解释,如收录于《中部》的《法嗣经》《谛分别经》《应习不应习经》等,即是沙利补答尊者详细解释佛陀简短开示的经典。佛陀入灭后,诸圣者、大长老们继续对三藏圣典进行注解诠释,这些注释文献即是上座部佛教的「义注」,它们是上座部佛教历代长老大德们传承佛陀教法的禅修精要和智慧结晶,也是对巴利语三藏圣典最为权威的解释。</p>
+<p>之后的古代的大长老们又用巴利语撰写了解释义注和根本的再注释书——复注。这些古代文献已经有上千年的历史。</p>
+<p>根据上座部佛教传统,巴利语三藏包含了根本,义注,复注在内的100多本书。共计800万单词。长期以来,这些文献以巴利语刻写在棕榈叶上在东南亚国家流传。</p>
+<p>将这些古代文献翻译为汉语,是众多佛教徒的心愿。</p>
+<p><a href="/pcd/community/list" class="font-bold">已经翻译的经文</a></p>
+</div>
+</div>
+</div>
+</div>
+
+
+<div id="callout"></div>
+<div class="bg-white dark:bg-gray-900 py-8 md:py-24">
+<div class="xl:container xl:mx-auto md:px-6 px-4">
+<div class="w-5/6 md:w-3/4 lg:w-2/3 xl:w-1/2 text-center mx-auto mb-16">
+<div class="text-xs md:text-sm opacity-75 font-semibold uppercase tracking-wide text-gray-700 dark:text-gray-300">
+翻译中心
+</div>
+<h2 class="mt-1 tracking-tight leading-tighter text-2xl sm:text-3xl md:text-4xl lg:text-5xl font-extrabold text-gray-900 dark:text-gray-100">
+wikipali(云台)翻译中心
+</h2>
+</div>
+<div class="flex md:flex-row-reverse justify-center md:justify-start flex-wrap md:flex-no-wrap">
+<div class="w-full md:w-1/2 md:pl-8 ">
+<img class="mb-8 md:mb-0 rounded-md" alt="/assets/gallery/03.jpg" src="/assets/gallery/02.jpg">
+</div>
+<div class="w-full md:w-1/2 md:pr-8 md:pr-8 mb-4 md:mb-0">
+<div class="md:text-lg prose">
+<p>wikipali(云台)翻译中心坐落于云南省昆明市宜良县,致力于整理三藏和佛教文献的翻译和研究。</p>
+<p>佛教文化是中国传统文化的一部分,也是全世界人类的宝贵文化遗产。然而, 由于很多佛教文献是由巴利语、梵语、缅语、泰文等记载,所以需要培养专门的小语种语言人才,进行相关的研究。</p>
+<p>我们的团队由一群热爱佛教文化的志愿者组成,来自不同的国家和地区,拥有不同的背景和经验。大家互相配合,致力于将佛教文献翻译成汉语,让更多人能够阅读和理解这些珍贵的文献</p>
+<p>我们的翻译工作主要集中在三藏经典,将传统的文献转换成为通俗的现代汉语。除此之外,我们也参与翻译佛教论著、传记、诗歌等多种形式的佛教文献,保留和研究其文学、历史价值。</p>
+<p>我们的翻译成果将会在wikipali网站上发布,供大家免费使用和阅读。感谢您对wikipali(云台)翻译中心的支持和关注!</p>
+<p style="display:none;"><a href="https://getgrav.org" class="btn mt-4 w-content block">Find out more...</a></p>
+</div>
+</div>
+</div>
+</div>
+</div>
+
+
+<div id="gallery"></div>
+<div class="bg-white dark:bg-gray-900 py-8 md:py-24">
+<div class="xl:container xl:mx-auto md:px-6 px-4">
+<div class="w-5/6 md:w-3/4 lg:w-2/3 xl:w-1/2 text-center mx-auto mb-16">
+<div class="text-xs md:text-sm opacity-75 font-semibold uppercase tracking-wide text-gray-700 dark:text-gray-300">
+欢迎加入翻译中心
+</div>
+<h2 class="mt-1 tracking-tight leading-tighter text-2xl sm:text-3xl md:text-4xl lg:text-5xl font-extrabold text-gray-900 dark:text-gray-100">
+翻译中心相册
+</h2>
+<div class="mt-3 text-base md:text-lg lg:text-xl prose">
+<p></p>
+</div>
+</div>
+<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-y-2 gap-x-2">
+
+@foreach ($gallery as $item)
+<div class="inline-flex overflow-hidden rounded-md group safari-corner-overflow-fix">
+<a href="{{ $item['image'] }}" class="glightbox inline-block" data-gallery="161b91e52e3b1158306a38186e6f5107" data-title="{{ $item['title'] }}" data-description=".{{ $item['id'] }}" data-type="image">
+<img class="duration-200 group-hover:scale-110 group-hover:filter group-hover:brightness-110" title="Climbing Hilly Peaks" alt="Climbing Hilly Peaks" src="{{ $item['image'] }}" />
+</a>
+</div>
+@endforeach
+
+
+<div class="hidden">
+@foreach ($gallery as $item)
+    <div class="glightbox-desc {{ $item['id'] }}">
+        <div class="prose">
+            <p>{{ $item['description'] }}</p>
+        </div>
+    </div>
+@endforeach
+
+</div>
+</div>
+</div>
+</div>
+<div id="features"></div>
+<div class="bg-white dark:bg-gray-900 py-8 md:py-24">
+<div class="xl:container xl:mx-auto md:px-6 px-4">
+<div class="w-5/6 md:w-3/4 lg:w-2/3 xl:w-1/2 text-center mx-auto mb-16">
+<div class="text-xs md:text-sm opacity-75 font-semibold uppercase tracking-wide text-gray-700 dark:text-gray-300">
+在线翻译|协作|巴利语学习
+</div>
+<h2 class="mt-1 tracking-tight leading-tighter text-2xl sm:text-3xl md:text-4xl lg:text-5xl font-extrabold text-gray-900 dark:text-gray-100">
+专门开发的巴利语学习和翻译工具
+</h2>
+<div class="mt-3 text-base md:text-lg lg:text-xl prose">
+<p>结合多年的教学与翻译经验。专门为巴利语教学和翻译定制的多种在线编辑工具。无需安装软件。支持各种桌面操作系统。</p>
+</div>
+</div>
+<div class="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-y-8 gap-x-8 ">
+
+<div class="flex duration-300 hover:scale-105">
+<div class="flex flex-col w-full rounded-md group hover:bg-gray-100 dark:hover:bg-gray-800">
+<div class="text-gray-500 group-hover:text-primary rounded-md p-3 text-center">
+<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-pencil inline-block w-16 h-16 stroke-current stroke-3/2 mx-auto" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+<path stroke="none" d="M0 0h24v24H0z" fill="none" />
+<path d="M4 20h4l10.5 -10.5a1.5 1.5 0 0 0 -4 -4l-10.5 10.5v4" />
+<line x1="13.5" y1="6.5" x2="17.5" y2="10.5" />
+</svg>
+</div>
+<h3 class="mb-2 text-base md:text-lg group-hover:text-primary text-center">
+在线翻译
+</h3>
+<div class="prose text-center">
+</div>
+</div>
+</div>
+
+<div class="flex duration-300 hover:scale-105">
+<div class="flex flex-col w-full rounded-md group hover:bg-gray-100 dark:hover:bg-gray-800">
+<div class="text-gray-500 group-hover:text-primary rounded-md p-3 text-center">
+<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-template inline-block w-16 h-16 stroke-current stroke-3/2 mx-auto" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+<path stroke="none" d="M0 0h24v24H0z" fill="none" />
+<rect x="4" y="4" width="16" height="4" rx="1" />
+<rect x="4" y="12" width="6" height="8" rx="1" />
+<line x1="14" y1="12" x2="20" y2="12" />
+<line x1="14" y1="16" x2="20" y2="16" />
+<line x1="14" y1="20" x2="20" y2="20" />
+</svg>
+</div>
+<h3 class="mb-2 text-base md:text-lg group-hover:text-primary text-center">
+术语模版
+</h3>
+<div class="prose text-center">
+</div>
+</div>
+</div>
+
+<div class="flex duration-300 hover:scale-105">
+<div class="flex flex-col w-full rounded-md group hover:bg-gray-100 dark:hover:bg-gray-800">
+<div class="text-gray-500 group-hover:text-primary rounded-md p-3 text-center">
+<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-bolt inline-block w-16 h-16 stroke-current stroke-3/2 mx-auto" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+<path stroke="none" d="M0 0h24v24H0z" fill="none" />
+<polyline points="13 3 13 10 19 10 11 21 11 14 5 14 13 3" />
+</svg>
+</div>
+<h3 class="mb-2 text-base md:text-lg group-hover:text-primary text-center">
+实时发布译文
+</h3>
+<div class="prose text-center">
+</div>
+</div>
+</div>
+
+<div class="flex duration-300 hover:scale-105">
+<div class="flex flex-col w-full rounded-md group hover:bg-gray-100 dark:hover:bg-gray-800">
+<div class="text-gray-500 group-hover:text-primary rounded-md p-3 text-center">
+<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-tag inline-block w-16 h-16 stroke-current stroke-3/2 mx-auto" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+<path stroke="none" d="M0 0h24v24H0z" fill="none" />
+<circle cx="8.5" cy="8.5" r="1" fill="currentColor" />
+<path d="M4 7v3.859c0 .537 .213 1.052 .593 1.432l8.116 8.116a2.025 2.025 0 0 0 2.864 0l4.834 -4.834a2.025 2.025 0 0 0 0 -2.864l-8.117 -8.116a2.025 2.025 0 0 0 -1.431 -.593h-3.859a3 3 0 0 0 -3 3z" />
+</svg>
+</div>
+<h3 class="mb-2 text-base md:text-lg group-hover:text-primary text-center">
+在线讨论校对
+</h3>
+<div class="prose text-center">
+</div>
+</div>
+</div>
+
+<div class="flex duration-300 hover:scale-105">
+<div class="flex flex-col w-full rounded-md group hover:bg-gray-100 dark:hover:bg-gray-800">
+<div class="text-gray-500 group-hover:text-primary rounded-md p-3 text-center">
+<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-cloud-download inline-block w-16 h-16 stroke-current stroke-3/2 mx-auto" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+<path stroke="none" d="M0 0h24v24H0z" fill="none" />
+<path d="M19 18a3.5 3.5 0 0 0 0 -7h-1a5 4.5 0 0 0 -11 -2a4.6 4.4 0 0 0 -2.1 8.4" />
+<line x1="12" y1="13" x2="12" y2="22" />
+<polyline points="9 19 12 22 15 19" />
+</svg>
+</div>
+<h3 class="mb-2 text-base md:text-lg group-hover:text-primary text-center">
+译文导出
+</h3>
+<div class="prose text-center">
+</div>
+</div>
+</div>
+
+<div class="flex duration-300 hover:scale-105"  style="display:none;">
+<div class="flex flex-col w-full rounded-md group hover:bg-gray-100 dark:hover:bg-gray-800">
+<div class="text-gray-500 group-hover:text-primary rounded-md p-3 text-center">
+<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-apps inline-block w-16 h-16 stroke-current stroke-3/2 mx-auto" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+<path stroke="none" d="M0 0h24v24H0z" fill="none" />
+<rect x="4" y="4" width="6" height="6" rx="1" />
+<rect x="4" y="14" width="6" height="6" rx="1" />
+<rect x="14" y="14" width="6" height="6" rx="1" />
+<line x1="14" y1="7" x2="20" y2="7" />
+<line x1="17" y1="4" x2="17" y2="10" />
+</svg>
+</div>
+<h3 class="mb-2 text-base md:text-lg group-hover:text-primary text-center">
+Powerful Plugins
+</h3>
+<div class="prose text-center">
+</div>
+</div>
+</div>
+
+<div class="flex duration-300 hover:scale-105"  style="display:none;">
+<div class="flex flex-col w-full rounded-md group hover:bg-gray-100 dark:hover:bg-gray-800">
+<div class="text-gray-500 group-hover:text-primary rounded-md p-3 text-center">
+<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-device-desktop inline-block w-16 h-16 stroke-current stroke-3/2 mx-auto" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+<path stroke="none" d="M0 0h24v24H0z" fill="none" />
+<rect x="3" y="4" width="18" height="12" rx="1" />
+<line x1="7" y1="20" x2="17" y2="20" />
+<line x1="9" y1="16" x2="9" y2="20" />
+<line x1="15" y1="16" x2="15" y2="20" />
+</svg>
+</div>
+<h3 class="mb-2 text-base md:text-lg group-hover:text-primary text-center">
+Intuitive UI
+</h3>
+<div class="prose text-center">
+</div>
+</div>
+</div>
+
+<div class="flex duration-300 hover:scale-105">
+<div class="flex flex-col w-full rounded-md group hover:bg-gray-100 dark:hover:bg-gray-800">
+<div class="text-gray-500 group-hover:text-primary rounded-md p-3 text-center">
+<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-file-text inline-block w-16 h-16 stroke-current stroke-3/2 mx-auto" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+<path stroke="none" d="M0 0h24v24H0z" fill="none" />
+<path d="M14 3v4a1 1 0 0 0 1 1h4" />
+<path d="M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z" />
+<line x1="9" y1="9" x2="10" y2="9" />
+<line x1="9" y1="13" x2="15" y2="13" />
+<line x1="9" y1="17" x2="15" y2="17" />
+</svg>
+</div>
+<h3 class="mb-2 text-base md:text-lg group-hover:text-primary text-center">
+社区字典
+</h3>
+<div class="prose text-center">
+</div>
+</div>
+</div>
+
+<div class="flex duration-300 hover:scale-105">
+<div class="flex flex-col w-full rounded-md group hover:bg-gray-100 dark:hover:bg-gray-800">
+<div class="text-gray-500 group-hover:text-primary rounded-md p-3 text-center">
+<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-language inline-block w-16 h-16 stroke-current stroke-3/2 mx-auto" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+<path stroke="none" d="M0 0h24v24H0z" fill="none" />
+<path d="M4 5h7" />
+<path d="M9 3v2c0 4.418 -2.239 8 -5 8" />
+<path d="M5 9c-.003 2.144 2.952 3.908 6.7 4" />
+<path d="M12 20l4 -9l4 9" />
+<path d="M19.1 18h-6.2" />
+</svg>
+</div>
+<h3 class="mb-2 text-base md:text-lg group-hover:text-primary text-center">
+多语言译文对照
+</h3>
+<div class="prose text-center">
+</div>
+</div>
+</div>
+
+<div class="flex duration-300 hover:scale-105"  style="display:none;">
+<div class="flex flex-col w-full rounded-md group hover:bg-gray-100 dark:hover:bg-gray-800">
+<div class="text-gray-500 group-hover:text-primary rounded-md p-3 text-center">
+<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-users inline-block w-16 h-16 stroke-current stroke-3/2 mx-auto" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+<path stroke="none" d="M0 0h24v24H0z" fill="none" />
+<circle cx="9" cy="7" r="4" />
+<path d="M3 21v-2a4 4 0 0 1 4 -4h4a4 4 0 0 1 4 4v2" />
+<path d="M16 3.13a4 4 0 0 1 0 7.75" />
+<path d="M21 21v-2a4 4 0 0 0 -3 -3.85" />
+</svg>
+</div>
+<h3 class="mb-2 text-base md:text-lg group-hover:text-primary text-center">
+多人协作
+</h3>
+<div class="prose text-center">
+</div>
+</div>
+</div>
+
+<div class="flex duration-300 hover:scale-105"  style="display:none;">
+<div class="flex flex-col w-full rounded-md group hover:bg-gray-100 dark:hover:bg-gray-800">
+<div class="text-gray-500 group-hover:text-primary rounded-md p-3 text-center">
+<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-photo inline-block w-16 h-16 stroke-current stroke-3/2 mx-auto" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+<path stroke="none" d="M0 0h24v24H0z" fill="none" />
+<line x1="15" y1="8" x2="15.01" y2="8" />
+<rect x="4" y="4" width="16" height="16" rx="3" />
+<path d="M4 15l4 -4a3 5 0 0 1 3 0l5 5" />
+<path d="M14 14l1 -1a3 5 0 0 1 3 0l2 2" />
+</svg>
+</div>
+<h3 class="mb-2 text-base md:text-lg group-hover:text-primary text-center">
+Image Processing
+</h3>
+<div class="prose text-center">
+</div>
+</div>
+</div>
+
+<div class="flex duration-300 hover:scale-105">
+<div class="flex flex-col w-full rounded-md group hover:bg-gray-100 dark:hover:bg-gray-800">
+<div class="text-gray-500 group-hover:text-primary rounded-md p-3 text-center">
+<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-notebook inline-block w-16 h-16 stroke-current stroke-3/2 mx-auto" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+<path stroke="none" d="M0 0h24v24H0z" fill="none" />
+<path d="M6 4h11a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-11a1 1 0 0 1 -1 -1v-14a1 1 0 0 1 1 -1m3 0v18" />
+<line x1="13" y1="8" x2="15" y2="8" />
+<line x1="13" y1="12" x2="15" y2="12" />
+</svg>
+</div>
+<h3 class="mb-2 text-base md:text-lg group-hover:text-primary text-center">
+文集
+</h3>
+<div class="prose text-center">
+</div>
+</div>
+</div>
+
+<div class="flex duration-300 hover:scale-105"  style="display:none;">
+<div class="flex flex-col w-full rounded-md group hover:bg-gray-100 dark:hover:bg-gray-800">
+<div class="text-gray-500 group-hover:text-primary rounded-md p-3 text-center">
+<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-brand-github inline-block w-16 h-16 stroke-current stroke-3/2 mx-auto" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+<path stroke="none" d="M0 0h24v24H0z" fill="none" />
+<path d="M9 19c-4.3 1.4 -4.3 -2.5 -6 -3m12 5v-3.5c0 -1 .1 -1.4 -.5 -2c2.8 -.3 5.5 -1.4 5.5 -6a4.6 4.6 0 0 0 -1.3 -3.2a4.2 4.2 0 0 0 -.1 -3.2s-1.1 -.3 -3.5 1.3a12.3 12.3 0 0 0 -6.2 0c-2.4 -1.6 -3.5 -1.3 -3.5 -1.3a4.2 4.2 0 0 0 -.1 3.2a4.6 4.6 0 0 0 -1.3 3.2c0 4.6 2.7 5.7 5.5 6c-.6 .6 -.6 1.2 -.5 2v3.5" />
+</svg>
+</div>
+<h3 class="mb-2 text-base md:text-lg group-hover:text-primary text-center">
+On Github
+</h3>
+<div class="prose text-center">
+</div>
+</div>
+</div>
+
+<div class="flex duration-300 hover:scale-105">
+<div class="flex flex-col w-full rounded-md group hover:bg-gray-100 dark:hover:bg-gray-800">
+<div class="text-gray-500 group-hover:text-primary rounded-md p-3 text-center">
+<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-device-mobile inline-block w-16 h-16 stroke-current stroke-3/2 mx-auto" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+<path stroke="none" d="M0 0h24v24H0z" fill="none" />
+<rect x="7" y="4" width="10" height="16" rx="1" />
+<line x1="11" y1="5" x2="13" y2="5" />
+<line x1="12" y1="17" x2="12" y2="17.01" />
+</svg>
+</div>
+<h3 class="mb-2 text-base md:text-lg group-hover:text-primary text-center">
+手机APP
+</h3>
+<div class="prose text-center">
+</div>
+</div>
+</div>
+
+<div class="flex duration-300 hover:scale-105" >
+<div class="flex flex-col w-full rounded-md group hover:bg-gray-100 dark:hover:bg-gray-800">
+<div class="text-gray-500 group-hover:text-primary rounded-md p-3 text-center">
+<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-terminal inline-block w-16 h-16 stroke-current stroke-3/2 mx-auto" width="24" height="24" viewBox="0 0 1024 1024" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+<path
+        d="M523.4 936h-22.8l-4.5-1.8c-3.4-1.4-84.8-34.7-167.4-88.4C212.8 770.5 154 694.5 154 620V197.5c0-20.3 16.4-37 37.2-38.7L495.3 88h20.5l316.8 70.8c20.9 1.6 37.3 18.3 37.3 38.7V620c0 74.6-58.8 150.6-174.6 225.8-82.7 53.7-164 87-167.4 88.4l-4.5 1.8z m-12.9-50h3c17.8-7.6 87.1-38.2 155.2-82.6C737.7 758.5 820 690.3 820 620V207.2L510.3 138H501l-297 69.2V620c0 70.3 82.3 138.6 151.3 183.5 68.1 44.3 137.4 74.9 155.2 82.5z"
+        fill="currentColor" p-id="4788"></path>
+    <path
+        d="M693.5 394.1c-14.4-16.6-39.8-18.5-56.4-4.1L455.5 547 392 467.6c-13.7-17.2-39-20-56.2-6.3-17.2 13.7-20 39-6.3 56.2l88.9 111.2c12.7 15.9 35.2 19.5 52.1 9.1 3-1.5 5.9-3.3 8.5-5.6l210.3-181.8c16.7-14.3 18.6-39.7 4.2-56.3z"
+        fill="currentColor" p-id="4789"></path>
+</svg>
+
+</div>
+<h3 class="mb-2 text-base md:text-lg group-hover:text-primary text-center">
+安全
+</h3>
+<div class="prose text-center">
+</div>
+</div>
+</div>
+
+<div class="flex duration-300 hover:scale-105" style="display:none;">
+<div class="flex flex-col w-full rounded-md group hover:bg-gray-100 dark:hover:bg-gray-800">
+<div class="text-gray-500 group-hover:text-primary rounded-md p-3 text-center">
+<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-gift inline-block w-16 h-16 stroke-current stroke-3/2 mx-auto" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+<path stroke="none" d="M0 0h24v24H0z" fill="none" />
+<rect x="3" y="8" width="18" height="4" rx="1" />
+<line x1="12" y1="8" x2="12" y2="21" />
+<path d="M19 12v7a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2v-7" />
+<path d="M7.5 8a2.5 2.5 0 0 1 0 -5a4.8 8 0 0 1 4.5 5a4.8 8 0 0 1 4.5 -5a2.5 2.5 0 0 1 0 5" />
+</svg>
+</div>
+<h3 class="mb-2 text-base md:text-lg group-hover:text-primary text-center">
+Awesomazing
+</h3>
+<div class="prose text-center">
+</div>
+</div>
+</div>
+</div>
+</div>
+</div>
+<div id="contact"></div>
+<div class="bg-primary-darker text-primary-lighter py-8 md:py-24">
+<div class="xl:container xl:mx-auto md:px-6 px-4">
+<div class="w-5/6 md:w-3/4 lg:w-2/3 xl:w-1/2 text-center mx-auto mb-16">
+<div class="text-xs md:text-sm opacity-75 font-semibold uppercase tracking-wide text-gray-300">
+更多关于我们的信息
+</div>
+<h2 class="mt-1 tracking-tight leading-tighter text-2xl sm:text-3xl md:text-4xl lg:text-5xl font-extrabold text-gray-100">
+联络我们
+</h2>
+<div class="mt-3 text-base md:text-lg lg:text-xl prose">
+<p>wikipali@126.com</p>
+<p><span>请点击<a href="https://wj.qq.com/s2/13364158/ba70/" target="_blank" rel="noreferrer">腾讯问卷</a>填写您的反馈</span></p>
+</div>
+</div>
+<div class="max-w-xl mx-auto text-gray-700" style="display:none;">
+<form name="contact" action="#contact-us" method="POST" id="contact" class=" ">
+<div class="form-field  ">
+<div class="form-data" data-grav-field="text" data-grav-disabled data-grav-default="null">
+<div class="form-input-wrapper ">
+<input name="data[name]" value type="text" class="form-input " placeholder="Your&#x20;full&#x20;name" autocomplete="on" required="required" />
+</div>
+</div>
+</div>
+<div class="form-field  ">
+<div class="form-data" data-grav-field="email" data-grav-disabled data-grav-default="null">
+<div class="form-input-wrapper ">
+<input name="data[email]" value type="email" class="form-input " placeholder="Your&#x20;email&#x20;address" required="required" />
+</div>
+</div>
+</div>
+<div class="form-field  ">
+<div class="form-data" data-grav-field="text" data-grav-disabled data-grav-default="null">
+<div class="form-input-wrapper ">
+<input name="data[phone]" value type="text" class="form-input " placeholder="Your&#x20;phone&#x20;number&#x20;&#x28;optional&#x29;" />
+</div>
+</div>
+</div>
+<div class="form-field  ">
+<div class="form-data" data-grav-field="textarea" data-grav-disabled data-grav-default="null">
+<div class="form-textarea-wrapper  ">
+<textarea name="data[message]" class="form-textarea  " placeholder="Your message" required="required" rows="4"></textarea>
+</div>
+</div>
+</div>
+<input type="hidden" name="__form-name__" value="contact" />
+<input type="hidden" name="__unique_form_id__" value="ix2wof4ukdnschp3i1bc" />
+<input type="hidden" name="form-nonce" value="a4618725adb330b36829801d1b7a11d2" />
+<div class="text-center">
+<button type="submit" class="form-button no-default-style text-white bg-gray-700 hover:bg-primary">Submit Form</button>
+</div>
+</form>
+</div>
+</div>
+</div>
+</div>
+</section>
+<footer class="bg-gray-100 dark:bg-gray-800 border-t border-gray-200 dark:border-gray-700 text-sm">
+<div class="xl:container xl:mx-auto md:px-6 px-4 py-8">
+<div class="relative flex flex-col md:flex-row justify-between min-h-16 text-gray-600 dark:text-gray-500">
+    <div style="display:flex;">
+    @if(!empty(config('mint.app.icp_code')))
+    <span>ICP:<a href="https://beian.miit.gov.cn/" target="_blank" rel="noreferrer">{{ config('mint.app.icp_code') }}</a></span>
+    <span style="display:flex;">
+        <img alt="code" src="{{ URL::asset('assets/images/logo_mps.png') }}" style="width: 20px; height: 20px;margin:0 12px;"/>
+        @if(empty(config('mint.app.mps_code')))
+        <span>滇公网安备[审批中]号</span>
+        @else
+        <span>{{ config('mint.app.mps_code') }}</span>
+        @endif
+    </span>
+    @endif
+    </div>
+</div>
+<div style="display:none;" class="relative flex flex-col md:flex-row justify-between min-h-16 text-gray-600 dark:text-gray-500">
+    <div class="flex font-medium space-x-6 md:space-x-8 items-center justify-center mb-6 md:mb-0 md:justify-start ">
+    <a href="/typhoon/onepage/#" class="hover:text-primary transition duration-300">Terms &amp; Conditions</a>
+    <a href="/typhoon/onepage/#" class="hover:text-primary transition duration-300">Privacy Policy</a>
+    </div>
+    <div class="flex social mb-2 space-x-2 items-center justify-center mb-6 md:mb-0 md:justify-start">
+    <a href="https://twitter.com/getgrav" aria-label="twitter" class="text-twitter  hover:filter hover:brightness-110 transition duration-300">
+    <svg class="inline-block w-8 h-8 fill-current stroke-current" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 960 960"><path d="M480 0c133.333 0 246.667 46.667 340 140s140 206.667 140 340c0 132-46.667 245-140 339S613.333 960 480 960c-132 0-245-47-339-141S0 612 0 480c0-133.333 47-246.667 141-340S348 0 480 0m196 392c20-14.667 35.333-30.667 46-48-21.333 8-39.333 12.667-54 14 20-12 34-29.333 42-52-20 10.667-40 18-60 22-18.667-18.667-42-28-70-28-26.667 0-49 9.333-67 28s-27 40.667-27 66c0 1.333.333 4.667 1 10s1 9.333 1 12c-80-4-144.667-37.333-194-100-9.333 16-14 32-14 48 0 33.333 14.667 59.333 44 78-17.333 0-32-4-44-12v2c0 22.667 7 42.667 21 60s32.333 28 55 32c-10.667 2.667-18.667 4-24 4-8 0-14-.667-18-2 13.333 44 42.667 66 88 66-33.333 26.667-72.667 40-118 40h-22c45.333 28 93.333 42 144 42 81.333 0 146.667-27.667 196-83s74-117.667 74-187v-12" /></svg>
+    </a>
+    <a href="https://github.com/getgrav" aria-label="github" class="text-github dark:text-gray-500 hover:filter hover:brightness-110 transition duration-300">
+    <svg class="inline-block w-8 h-8 fill-current stroke-current" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 960 960"><path d="M480 476c10.667 0 24.667-.667 42-2s31-2 41-2 20.667 1.333 32 4c11.333 2.667 21 7.333 29 14 17.333 17.333 26 37.333 26 60 0 42.667-14.333 70.667-43 84-28.667 13.333-71 20-127 20s-98.333-6.667-127-20-43-41.333-43-84c0-22.667 8.667-42.667 26-60 8-6.667 17.667-11.333 29-14 11.333-2.667 22-4 32-4s23.667.667 41 2 31.333 2 42 2m-80 128c9.333 0 17-4.667 23-14s9-20 9-32c0-30.667-10.667-46-32-46s-32 15.333-32 46c0 12 3 22.667 9 32 6 9.333 13.667 14 23 14m160 0c9.333 0 17.333-4.667 24-14 6.667-9.333 10-20 10-32 0-13.333-3.333-24.333-10-33-6.667-8.667-14.667-13-24-13-21.333 0-32 15.333-32 46 0 12 3 22.667 9 32 6 9.333 13.667 14 23 14M480 0c133.333 0 246.667 46.667 340 140s140 206.667 140 340c0 132-46.667 245-140 339S613.333 960 480 960c-132 0-245-47-339-141S0 612 0 480c0-133.333 47-246.667 141-340S348 0 480 0m44 676c125.333 0 188-61.333 188-184 0-37.333-12.667-70-38-98 2.667-2.667 3-16.333 1-41s-7.667-48.333-17-71c-29.333 4-67.333 21.333-114 52-13.333-4-34.667-6-64-6-26.667 0-48 2-64 6-20-13.333-39.667-24.333-59-33-19.333-8.667-33-14.333-41-17l-14-2c-9.333 22.667-15 46.333-17 71s-1.667 38.333 1 41c-25.333 28-38 60.667-38 98 0 122.667 62.667 184 188 184h88" /></svg>
+    </a>
+    </div>
+</div>
+<div class="relative flex flex-col md:flex-row justify-between mt-0 md:mt-6 text-gray-600 dark:text-gray-500 md:items-center">
+<div class="text-center md:text-left mb-6 md:mb-0">
+<p>本页面模版基于<a href="https://getgrav.org/premium/typhoon/docs">Grav Typhoon</a>制作</p>
+</div>
+<div class="max-w-64 mx-auto md:mx-0">
+<div class="theme-chooser flex items-center rounded-md border border-gray-300 dark:border-gray-600 pl-2 pr-0">
+<span>
+<span x-cloak :class="{'inline-block' : appearance === 'system', 'hidden': appearance !== 'system'}">
+<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-device-desktop inline-block w-6 h-6 stroke-current" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+<path stroke="none" d="M0 0h24v24H0z" fill="none" />
+<rect x="3" y="4" width="18" height="12" rx="1" />
+<line x1="7" y1="20" x2="17" y2="20" />
+<line x1="9" y1="16" x2="9" y2="20" />
+<line x1="15" y1="16" x2="15" y2="20" />
+</svg>
+</span>
+<span x-cloak :class="{'inline-block' : appearance === 'light', 'hidden': appearance !== 'light'}">
+<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-sun inline-block w-6 h-6 stroke-current" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+<path stroke="none" d="M0 0h24v24H0z" fill="none" />
+<circle cx="12" cy="12" r="4" />
+<path d="M3 12h1m8 -9v1m8 8h1m-9 8v1m-6.4 -15.4l.7 .7m12.1 -.7l-.7 .7m0 11.4l.7 .7m-12.1 -.7l-.7 .7" />
+</svg>
+</span>
+<span x-cloak :class="{'inline-block' : appearance === 'dark', 'hidden': appearance !== 'dark'}">
+<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-moon inline-block w-6 h-6 stroke-current" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+<path stroke="none" d="M0 0h24v24H0z" fill="none" />
+<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z" />
+</svg>
+</span>
+</span>
+<select x-model="appearance" @change="typhoonStore({ appearance: $event.target.value });" class="form-select focus:ring-transparent focus:outline-none focus:shadow-none" aria-label="Change color theme">
+<option value="system" :selected="appearance === 'system'">System</option>
+<option value="light" :selected="appearance === 'light'">Light</option>
+<option value="dark" :selected="appearance === 'dark'">Dark</option>
+</select>
+</div>
+</div>
+</div>
+</div>
+</footer>
+<div :class="{ 'invisible': !show_mobile_nav, 'opacity-100': show_mobile_nav }" class="mobile-nav invisible z-20 overflow-hidden transition duration-500 h-screen w-screen absolute top-0 flex flex-col items-center justify-around absolute opacity-0 bg-gray-800 transition duration-500">
+<div class="overflow-y-auto w-full py-12 pl-2 pr-12 sm:p-12">
+<ul class="flex flex-col text-gray-300 text-left w-full">
+@foreach ($nav as $item)
+<li x-data="{ selected: true }" class="text-lg pl-2 border-t border-gray-700 py-2 active ">
+<div class="flex w-full h-full">
+<a class="w-full transition duration-300 hover:text-primary" href="{{ $item['link'] }}">{{ $item['title'] }}</a>
+</div> </li>
+@endforeach
+</ul>
+</div>
+<div class="absolute top-2 right-2">
+<button @click="show_mobile_nav = false" aria-label="Close button" type="button" class="inline-flex items-center justify-center p-2 rounded-md text-white hover:text-primary focus:outline-none focus:text-gray-800 transition duration-150 ease-in-out">
+<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-x inline-block h-8 w-8 text-gray-300 hover:text-white" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+<path stroke="none" d="M0 0h24v24H0z" fill="none" />
+<line x1="18" y1="6" x2="6" y2="18" />
+<line x1="6" y1="6" x2="18" y2="18" />
+</svg>
+</button>
+</div>
+</div>
+</div>
+<script>
+window.GravForm = window.GravForm || {};
+    window.GravForm.config = {
+        current_url: '/typhoon/onepage',
+        current_params: [],
+        param_sep: ':',
+        base_url_relative: '/typhoon/onepage',
+        form_nonce: 'a4618725adb330b36829801d1b7a11d2',
+        session_timeout: 1800
+    };
+    window.GravForm.translations = Object.assign({}, window.GravForm.translations || {}, { PLUGIN_FORM: {} });
+</script>
+<script src="/assets/typhoon/js/glightbox.min.js"></script>
+<script src="/assets/typhoon/js/appearance.js"></script>
+<script>
+const lightbox = GLightbox({"selector":"[rel=\"lightbox\"], .glightbox","width":"90vw","height":"auto"});
+</script>
+
+<script>
+    let api = "{{ $api }}/auth/current";
+    const key = "token";
+    let token = sessionStorage.getItem(key);
+    if(token){
+        console.log('api',api);
+        const response = fetch(
+            api,
+            {
+                credentials: "include",
+                headers: {
+                    Authorization: 'Bearer ' + token,
+                    "Content-Type": "application/json; charset=utf-8",
+                    },
+                mode: "cors",
+                method: 'GET',
+            }
+        ).then((response) => response.json())
+        .then((json) => {
+            if(json.ok){
+                document.getElementById('nickname').innerHTML = 'Hi! ' + json.data.nickName;
+            }else{
+                document.getElementById("sign_in").style.display = "block";
+            }
+            console.log('user',json);
+        });
+    }else{
+        console.error('no token');
+        document.getElementById("sign_in").style.display = "block";
+
+    }
+</script>
+
+</body>
+</html>

+ 19 - 0
api-v12/resources/views/wbwanalyses.blade.php

@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+    <body>
+        <h1>逐词解析数据分析</h1>
+        <table>
+        @foreach($data as $row)
+        <tr>
+        <td>{{ $row->d1 }}</td>
+        <td>{{ $row->data }}</td>
+        <td style='width:500px;'><span style='display:inline-block;width:{{ $row->ct }}px;background-color:green;'>{{ $row->ct }}</span></td>
+        </tr>
+        @endforeach
+        </table>
+
+        <script>
+        var app = @json($data);
+        </script>
+    </body>
+</html>

Деякі файли не було показано, через те що забагато файлів було змінено